Commit Graph
21 Commits
Author SHA1 Message Date
marcandClaude Opus 5 e9e07f9bed fix(ui): schmale Geraete zeigten nur eine Kachelspalte
Auf 360px (Galaxy Z Flip 7 aufgeklappt) brauchten zwei Spalten
2x160 + 12 = 332px, verfuegbar waren nach 20px Innenrand aber nur
320px - also fiel das Raster auf eine Spalte zurueck.

Schmal jetzt 132px Mindestbreite, 10px Abstand, 12px Innenrand. Damit
stehen zwei Spalten ab 300px Fensterbreite, ohne dass breite Schirme
sich aendern (dort weiter 160px und 20px).

Raster und Innenrand stehen als Klassen in index.css: inline gesetzt
haette die Media-Query sie nicht erreicht - derselbe Fehler wie zuletzt
in der Kopfleiste.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 16:11:27 +02:00
marcandClaude Opus 5 0ef7bd67ab feat(webdav): Anleitung zum Einhaengen neben den App-Passwoertern
Ein Info-Knopf unter Einstellungen -> Access oeffnet drei Wege:
Windows (Netzlaufwerk), Linux ueber davfs2 samt fstab und secrets, und
Linux ueber den Dateimanager. Dazu WebDAV-Adresse, Benutzername und
Cloud-Adresse zum Kopieren.

Die WebDAV-Adresse stand bisher nirgends in der Oberflaeche - sie ist
zwar ableitbar, aber nur wenn man weiss, dass es sie gibt. Sie entsteht
aus window.location statt aus PUBLIC_URL: Was im Browser traegt, traegt
auch im Dateimanager.

Mitgenommen sind die drei Stellen, an denen es sonst scheitert: Windows
bricht ohne HTTPS ab und laedt nichts ueber 50 MB, die Konsole braucht
davfs2, und Dateimanager wollen davs:// statt https://.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 14:49:57 +02:00
marcandClaude Opus 5 9a2f90c89b fix(ui): Kopfleiste auf dem Handy hatte 0px Abstand nach oben
Die Regeln der schmalen Ansicht griffen nie: Ein Inline-Stil schlägt
jede Klassenregel, und `padding: '0 14px'` samt `paddingTop:
var(--safe-top)` stand genau dort. Gemessen kam padding-top als 0px an
statt als 8px - Titel und Nutzerbereich klebten am oberen Fensterrand.
Alle Abstaende stehen jetzt im CSS-Block, schmal 14px oben und 10px
unten.

Dazu das mitgelieferte App-Symbol neu gezeichnet: Die drei PNG lagen
als Graustufen vor, der indigo Verlauf war zu Schwarz eingeebnet. Die
Wolke besteht jetzt aus drei Kreisen und einem Rechteck dazwischen -
gerade Unterkante, keine Kerben in der Silhouette.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 14:26:49 +02:00
marcandClaude Opus 5 9f44215698 feat(oidc): Profilbild vom Identitätsanbieter übernehmen
Schickt der Anbieter ein `picture`, wird es bei der Anmeldung geholt,
mittig auf 256x256 zugeschnitten und oben rechts angezeigt. Fehlt es
oder scheitert das Holen, bleibt es beim Buchstabenkreis - die
Anmeldung selbst hängt nicht davon ab.

Die Bildadresse kommt aus einem Token, also von außen. Erlaubt ist
deshalb ausschließlich der Ursprung aus OIDC_ISSUER, Weiterleitungen
eingeschlossen; dazu 4 MB und 5 Sekunden als Deckel. Ohne das wäre es
eine Aufforderung an den Server, für einen Fremden beliebige Adressen
im internen Netz anzufragen.

Neu: Migration 000019 (avatar_key/-source/-updated_at), Paket
internal/avatar, Route GET /api/v1/users/{id}/avatar. Der GC durchsucht
"avatars/" mit und kennt die Schlüssel - sonst räumte er die Bilder
nach einem Tag weg.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 13:43:22 +02:00
HoneyandClaude Opus 5 3019e84681 feat(oidc): OIDC_BUTTON_LABEL, und vier kaputte Zeilen in .env.example
Der Knopf hiess fest "Sign in with SSO / OIDC". Der Anbieter heisst bei
jedem anders; "Anmelden mit PocketID" sagt dem, der davorsteht, mehr.
Vorgabe unveraendert. Der Wert geht nur ueber /public/config, wenn OIDC
ueberhaupt an ist.

Beim Testen dabei selbst einen Fehler gebaut und eingefangen: Ein
Kommentar hinter einem LEEREN Wert wird in einer .env zum Wert.
OIDC_ISSUER= # z. B. https://... startete den OIDC-Aufbau mit dem
Kommentartext als Adresse, und der Start brach ab.

In deploy/.env.example steckten vier weitere solche Zeilen, darunter
OFFICE_PROVIDER= # collabora | onlyoffice - Office waere mit Unsinn als
Anbieter eingeschaltet worden. Alle umgestellt, Warnung an den Dateikopf.

Dazu im README belegt, was beim Ausschalten der Versionierung passiert:
Fassungen bleiben, auch im Papierkorb; erst das Leeren entfernt sie samt
Blobs, und zwar sofort statt erst beim GC.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 13:08:31 +02:00
HoneyandClaude Opus 5 617c665a2e fix(oidc): klare Meldung bei einem OIDC_ISSUER ohne Schema
OIDC_ISSUER=PocketID (der Name statt der Adresse) endete in
unsupported protocol scheme "" – tief aus der Bibliothek, ohne Hinweis
auf die Ursache. Und weil ein Fehlschlag hier den Start abbricht, stand
die ganze Cloud wegen einer Zeile in der .env.

Jetzt wird vorher geprueft und die Zeile beim Namen genannt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 13:01:21 +02:00
HoneyandClaude Opus 5 ebff565367 feat(files): MAX_VERSIONS_KEPT statt zweier Konstanten
Die Zahl stand doppelt im Quelltext: als const im Backend und noch einmal
im Verlaufs-Dialog, verbunden nur durch den Kommentar "muss zu
maxVersionsKept im Backend passen". Ein Satz ist keine Zusicherung - beim
ersten Aendern haette der Dialog eine andere Zahl genannt als die, die der
Server anwendet.

Jetzt eine .env-Variable (Vorgabe 5), die der Server ueber
/api/v1/public/config mitliefert. Werte unter 1 werden verworfen: Die Zahl
geht als OFFSET in die Aufraeumabfrage, und OFFSET 0 loeschte jede Fassung -
aus "keine Grenze" wuerde "kein Verlauf".

Gemessen: MAX_VERSIONS_KEPT=3, Datei siebenmal ueberschrieben, uebrig
bleiben v6, v5, v4 bei aktueller v7.

Dazu ein README-Abschnitt "Versionen" - Standard aus, warum das so ist,
Kontingent, und dass jedes Strg+S in Office eine Fassung anlegt. Bisher
stand zu alldem nichts im README.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:58:12 +02:00
HoneyandClaude Opus 5 7fc8bb51d5 docs: Doku nach fuenf Runden aufraeumen
Nach dem Hin und Her um Profile, Ports und Escaping war Sediment
liegengeblieben:

- README: "Drei Adressen fuer drei Richtungen" stand zweimal; die
  Profil-Erklaerung war eine Chronik ("das war nicht immer so") statt
  einer Anleitung. Jetzt ein Absatz.
- .env.example (beide): der Office-Block begann mit einem Hinweis auf
  COMPOSE_PROFILES, den man nur braucht, wenn man selbst ein Profil
  anlegt - als erste Zeile eines Abschnitts unbrauchbar. Raus.
- TESTING: der grosse Office-Abschnitt behauptete noch "Getestet mit
  Collabora im Compose-Profil office" und pruefte "ohne --profile startet
  der Container nicht". Beides ueberholt.
- Umlaute vereinheitlicht (laeuft neben gehoert), $-Hinweis von vier auf
  zwei Zeilen.

Dazu zwei neue Zeilen in der Fehlertabelle des README: Container entsteht
gar nicht (Profil) und Container laeuft, aber kein Menuepunkt (leerer
OFFICE_PROVIDER oder falscher Port).

Geprueft: beide Compose-Dateien gueltig, jeder Schluessel aus dem Code
steht in deploy/.env.example, keine doppelten Absaetze mehr.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:27:19 +02:00
HoneyandClaude Opus 5 9f5b003177 docs(env): Office-Port haengt vom Anbieter ab
OFFICE_URL stand fest auf http://office:9980 – das ist Collabora. OnlyOffice
und Euro-Office lauschen im Container auf 80, dort waere die Adresse
http://office ohne Port. Mit dem falschen Port meldet die Discovery nichts
und der Menuepunkt bleibt weg.

Dazu deutlicher: leerer OFFICE_PROVIDER heisst aus, auch wenn der Container
laeuft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:23:57 +02:00
HoneyandClaude Opus 5 bad958d886 fix(office): Schnipsel ohne Profil – sie starten jetzt beim Einfuegen
profiles: [office] war als Sparmassnahme gedacht: Der Container laeuft nur
auf Wunsch. In Portainer/Dockge/Komodo gibt es aber kein --profile, und der
Dienst entstand dort nie – ohne Fehlermeldung, ohne Hinweis, ohne Weg ueber
die Bedienung.

Eine Voreinstellung, bei der das Einfuegen des Schnipsels nichts bewirkt,
ist die falsche. Alle drei Schnipsel starten jetzt mit  (geprueft: app office postgres). Abschalten: docker compose stop
office. Wer ein Profil will, haengt die Zeile selbst an.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:21:23 +02:00
HoneyandClaude Opus 5 deee0662d0 docs(office): COMPOSE_PROFILES statt --profile fuer Oberflaechen
Der Office-Container entstand nie, ohne Fehlermeldung: profiles: [office]
startet nur mit --profile office, und in Portainer/Dockge/Komodo gibt es
diesen Schalter gar nicht.

COMPOSE_PROFILES=office in der .env wirkt genauso und braucht keine
Kommandozeile – Compose liest die Variable fuer sich selbst. Gemessen mit
den echten Dateien: ohne die Zeile 'app postgres', mit ihr
'app office postgres'.

Steht jetzt in beiden .env.example, beiden Compose-Kopfzeilen, README und
TESTING.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:09:56 +02:00
HoneyandClaude Opus 5 4865fc47f8 docs(office): OFFICE_JWT_SECRET fehlte in beiden .env.example
Die README-Schnipsel fuer OnlyOffice und Euro-Office verlangen
OFFICE_JWT_SECRET, in den Beispieldateien stand es nicht – Compose warnt
dann nur 'variable is not set' und der Dokumentenserver laeuft mit leerem
Geheimnis.

Dazu praeziser, wo es bei OnlyOffice/Euro-Office nach Aktenlage haken
wuerde: IP-Filter des Integrators und Proof-Key-Signatur. Beides
ungeprueft, aber besser benannt als verschwiegen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:04:55 +02:00
HoneyandClaude Opus 5 213ecb7d06 docs(env): klarstellen, dass $$ als ein $ ankommt
Nachfrage aus der Praxis: printenv zeigt nach dem Escapen ein einzelnes $,
und das sah nach einem zweiten Fehler aus. Es ist das gewuenschte Ergebnis –
angemeldet wird mit dem einfachen $. Dazu der Hinweis, dass einfache
Anfuehrungszeichen dasselbe ohne Verdopplung leisten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 12:00:59 +02:00
HoneyandClaude Opus 5 218b238afc fix(admin): Laenge des Seed-Passworts loggen, $-Falle dokumentieren
Ein $ im Wert wird von Docker Compose als Variable gelesen und schneidet
ab: Sicher$Passwort2026 kommt als Sicher an (gemessen). Angelegt wird ein
Konto mit einem Passwort, das niemand kennt; die Anmeldung scheitert mit
'invalid credentials', obwohl alles richtig eingetippt ist. Die Datenbank
laeuft dabei weiter, weil Postgres denselben abgeschnittenen Wert bekommt.

Der Start nennt jetzt die Laenge des Passworts (nicht den Wert) und warnt
unter 12 Zeichen mit dem Hinweis auf $$. Ohne diese Zahl war der Fehler
von aussen nicht zu sehen: Compose meldet zwar 'variable is not set', aber
auf stderr beim up, nicht im Container-Log.

Escape-Tabelle in README und beiden .env.example. Ein Backslash hilft
nicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 11:54:43 +02:00
HoneyandClaude Opus 5 370d8ce0c7 feat(deploy): APP_BIND – Port wahlweise nur lokal oder im Netz
Der Port war fest auf 127.0.0.1 gebunden. Richtig, solange ein Reverse
Proxy davorsteht – beim Ausprobieren in einer Testumgebung heißt es aber
ERR_CONNECTION_REFUSED, sobald man über die IP zugreift, und nichts im
Log deutet darauf hin: Der Kernel lehnt ab, bevor die Anwendung etwas
davon sieht.

APP_BIND ist jetzt eine Variable, Vorgabe bleibt 127.0.0.1. Gilt für die
App und für die Office-Container in allen drei README-Schnipseln.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 11:45:47 +02:00
HoneyandClaude Opus 5 428fd2672c docs(env): Beispieldateien kürzen, Erklärungen ins README
Die beiden .env.example zusammen waren 251 Zeilen für 40 Schlüssel – gut
gemeint, aber niemand liest einen Absatz pro Variable. Jetzt eine Zeile je
Schlüssel (58 + 89), die Begründungen stehen im README unter
'Einstellungen', gebündelt als die sieben Dinge, die nicht beim Start
auffallen, sondern später.

Dabei durch einen echten Start aus den Beispieldateien gefunden:
STORAGE_PATH fehlte, Vorgabe ./data wird im Container zu /app/data, und
der Start endete in 'mkdir /app/data: permission denied'. Das Abbild setzt
STORAGE_PATH und TMP_PATH jetzt selbst – es kennt seine Verzeichnisse
besser als eine Beispieldatei. Eine .env darf weiter überschreiben.

Geprüft: jeder Schlüssel, den die Anwendung liest, steht weiterhin in
deploy/.env.example; eine frische Instanz startet allein aus den beiden
Beispieldateien.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 11:27:31 +02:00
HoneyandClaude Opus 5 35ebf609b7 fix(config): Datenbank-Passwort mit Sonderzeichen bricht den Start
Die Verbindungszeichenkette wurde mit fmt.Sprintf zusammengeklebt. Ein
Passwort mit % und @ ergab eine kaputte URL:

  parse "postgres://aether:8UoNj%CoWJ7ze@qy@localhost:5432/aether":
  invalid URL escape "%Co"

Der Server kam nicht über die Migrationen hinaus. Die key=value-Form hätte
dasselbe Problem mit einem Leerzeichen gehabt, nur stiller.

config.DSN() liefert jetzt eine postgres://-URL, gebaut mit net/url und
net.JoinHostPort (klammert IPv6). pgxpool und golang-migrate nehmen sie
beide unverändert – dsnToURL, splitDSN, indexByte und orDefault in pkg/db
sind ersatzlos entfallen. Test deckt %, @, :, /, Leerzeichen und IPv6 ab.

Dazu: DB_HOST und DB_PORT fehlten in der schlanken .env.example, weshalb
localhost statt postgres gegriffen hat. APP_ENV ergänzt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 11:20:01 +02:00
HoneyandClaude Opus 5 16ab6f385b docs(office): OIDC ins schlanke Beispiel, Office-Server als Schnipsel
Das Wurzel-Beispiel enthielt keinen einzigen OIDC-Schlüssel – wer sich
über PocketID anmelden will, fand nirgends, wohin damit. Jetzt drin,
samt der Warnung zu OIDC_LINK_BY_USERNAME: vor der ersten Anmeldung
setzen, danach existiert das zweite Konto schon.

Der Office-Container ist aus dem Beispiel raus. Es gibt drei zur Auswahl,
jeder bringt eigene Variablen mit, und man will genau einen – sie stehen
jetzt als anhängbare Schnipsel im README (Collabora, OnlyOffice,
Euro-Office). Alle drei gegen das Beispiel geprüft: docker compose config
läuft durch.

Euro-Office (seit 09.06.2026, in Nextcloud Hub 26) ist ein
OnlyOffice-Fork und läuft über denselben Adapter – OFFICE_PROVIDER
bleibt onlyoffice, nur ein anderes Abbild.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 10:08:16 +02:00
HoneyandClaude Opus 5 13681958dd docs(deploy): schlankes Compose-Beispiel im Wurzelverzeichnis
Das Compose in deploy/ war zu über der Hälfte Kommentar (73 von 137
Zeilen) und mischte zwei Zwecke. Jetzt getrennt:

  Wurzel   docker-compose.example.yml + .env.example  – betreiben,
           zieht das fertige Abbild, braucht keinen Quelltext
  deploy/  docker-compose.yml + .env.example          – entwickeln,
           baut aus dem Quelltext, kennt alle Schalter

Die schlanke .env.example führt nur die Pflichtwerte und Office; die
vollständige Liste mit Erklärungen bleibt in deploy/.env.example.
Die kopierte /docker-compose.yml ist ignoriert – sie gehört in die
Umgebung, nicht ins Repo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:33:20 +02:00
HoneyandClaude Opus 5 62e80dd2f5 docs(deploy): Abbild unter Docker/Aether statt unter dem Nutzer
Das Abbild lag zuerst unter gitea…/honey/aether – also beim Nutzer statt
bei der Organisation, unter der die anderen Docker-Projekte liegen. Neuer
Pfad: gitea…/docker/aether, gleicher Digest. Das alte Paket ist gelöscht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:26:59 +02:00
HoneyandClaude Opus 5 31a027c93a feat(aether): initial commit – self-hosted Cloud, Phasen 1–7
Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA.
Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb,
Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming,
Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office
(Collabora/OnlyOffice).

Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort)
sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:25:36 +02:00