diff --git a/.env.example b/.env.example index e0b6277..3ceb2b9 100644 --- a/.env.example +++ b/.env.example @@ -15,6 +15,9 @@ DB_PORT=5432 DB_NAME=aether DB_USER=aether # Jedes Zeichen erlaubt, auch % @ : / und Leerzeichen. +# Ein $ im Wert wird von Docker Compose als Variable gelesen und schneidet +# lautlos ab: geheim$wort kommt als geheim an. Als $$ schreiben oder den +# ganzen Wert in 'einfache Anfuehrungszeichen' setzen. Ein \ hilft NICHT. DB_PASSWORD= # Verzeichnis auf dem Wirt. Nur lesend anfassen – zum Hineinlegen: WebDAV. @@ -34,6 +37,7 @@ APP_BIND=127.0.0.1 # ── Erster Start ────────────────────────────────────────────────────────────── # Legt den Admin an. Danach ADMIN_PASSWORD leeren. +# Auch hier: ein $ muss $$ heissen (siehe DB_PASSWORD). ADMIN_USERNAME=admin ADMIN_PASSWORD= diff --git a/README.md b/README.md index d5a0107..8f22fbd 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,28 @@ Start. Leerzeichen. Es gibt keine Liste erlaubter Zeichen – wer die erst nachschlagen muss, wählt am Ende ein schwächeres Passwort. +**Ein `$` ist die Ausnahme, und zwar in *jedem* Wert.** Docker Compose liest +es als Variable und schneidet lautlos ab. Gemessen: + +| in der `.env` | kommt an | +|---|---| +| `abc$def` | `abc` | +| `abc$$def` | `abc$def` ✓ | +| `'abc$def'` | `abc$def` ✓ | +| `abc\$def` | `abc\` | + +Ein Backslash hilft also **nicht**. Das trifft besonders `ADMIN_PASSWORD`: +Angelegt wird dann ein Konto mit einem Passwort, das niemand kennt, und die +Anmeldung scheitert mit „invalid credentials", obwohl alles richtig eingetippt +ist. Nachsehen, was wirklich angekommen ist: + +```bash +docker compose exec app printenv ADMIN_PASSWORD +``` + +Seit dem 24.08.2026 nennt der Start zusätzlich die **Länge** des Passworts und +warnt, wenn sie auffällig klein ist. + **`PUBLIC_URL`** ist die Adresse, unter der der **Browser** die Cloud sieht, ohne Schrägstrich am Ende. Ein falscher Wert startet klaglos und fällt erst auf, wenn ein Freigabe-Link oder ein OIDC-Rücksprung ins Leere zeigt. diff --git a/TESTING.md b/TESTING.md index b17cc43..4bcef3d 100644 --- a/TESTING.md +++ b/TESTING.md @@ -646,6 +646,45 @@ breiteste. --- +## „invalid credentials" beim ersten Admin-Login (24.08.2026) + +Symptom: frischer Start, `admin account ready` im Log, Volume mehrfach +gelöscht – und die Anmeldung mit den richtigen Daten gibt `401`. + +Ursache ist die `.env`, nicht der Code: **Ein `$` wird von Docker Compose als +Variable gelesen und schneidet den Wert ab.** Gemessen mit +`ADMIN_PASSWORD=Sicher$Passwort2026`: + +``` +angekommen ist: Sicher (6 statt 19 Zeichen) +Compose meldet dazu: The "Passwort2026" variable is not set. +``` + +Die Meldung erscheint auf stderr beim `up`, nicht im Container-Log – wer die +Logs im Nachhinein ansieht, sieht sie nie. Die Datenbank funktioniert dabei, +weil Postgres und Anwendung **denselben** abgeschnittenen Wert bekommen. + +Escapen: + +| in der `.env` | kommt an | +|---|---| +| `abc$def` | `abc` | +| `abc$$def` | `abc$def` ✓ | +| `'abc$def'` | `abc$def` ✓ | +| `abc\$def` | `abc\` | + +- [ ] `ADMIN_PASSWORD` mit `$$` → `password_length` stimmt, Anmeldung 200 🔎 + (gemessen: 19 Zeichen, Login 200) +- [ ] Ohne Escape → Warnung im Log „ADMIN_PASSWORD ist auffaellig kurz" 🔎 +- [ ] Nachsehen, was wirklich ankam: `docker compose exec app printenv + ADMIN_PASSWORD` + +> Der Start nennt seit dem 24.08.2026 die **Länge** des Passworts (nicht den +> Wert) und warnt unter 12 Zeichen. Ohne diese Zahl war der Fehler von außen +> nicht zu sehen. + +--- + ## Erreichbarkeit von außen (24.08.2026) `ERR_CONNECTION_REFUSED` beim Zugriff über die IP ist meist kein Fehler, diff --git a/backend/cmd/aether/main.go b/backend/cmd/aether/main.go index e9ed64f..adeb591 100644 --- a/backend/cmd/aether/main.go +++ b/backend/cmd/aether/main.go @@ -257,7 +257,29 @@ func main() { if err := seedAdmin(ctx, authStore, cfg.AdminUsername, cfg.AdminPassword); err != nil { log.Warn().Err(err).Msg("admin seed skipped") } else { - log.Info().Str("username", cfg.AdminUsername).Msg("admin account ready") + // Die **Länge** mit ins Log, nicht das Passwort. + // + // Anlass: Ein `$` in der .env verschluckt bei Docker Compose + // lautlos den Rest des Wertes – `geheim$wort` kommt als `geheim` + // an. Angelegt wird dann ein Konto mit einem Passwort, das + // niemand kennt, und die Anmeldung scheitert mit „invalid + // credentials", obwohl alles richtig eingetippt ist. Gemessen, + // und im Log war nichts davon zu sehen. + // + // Eine Zahl verrät nichts Brauchbares, macht den verschluckten + // Wert aber sofort sichtbar. + log.Info(). + Str("username", cfg.AdminUsername). + Int("password_length", len(cfg.AdminPassword)). + Msg("admin account ready") + if len(cfg.AdminPassword) < 12 { + log.Warn(). + Int("password_length", len(cfg.AdminPassword)). + Msg("ADMIN_PASSWORD ist auffaellig kurz – enthaelt es ein $? " + + "In der .env muss es als $$ geschrieben oder der Wert in " + + "'einfache Anfuehrungszeichen' gesetzt werden, sonst " + + "schneidet Docker Compose dort ab.") + } } } diff --git a/deploy/.env.example b/deploy/.env.example index 9d6a6db..f52310f 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -18,6 +18,9 @@ DB_PORT=5432 DB_NAME=aether DB_USER=aether # Jedes Zeichen erlaubt, auch % @ : / und Leerzeichen. +# Ein $ im Wert wird von Docker Compose als Variable gelesen und schneidet +# lautlos ab: geheim$wort kommt als geheim an. Als $$ schreiben oder den +# ganzen Wert in 'einfache Anfuehrungszeichen' setzen. Ein \ hilft NICHT. DB_PASSWORD=changeme_strong_password # ── Sitzung ─────────────────────────────────────────────────────────────────── @@ -40,6 +43,7 @@ APP_BIND=127.0.0.1 # ── Erster Start ────────────────────────────────────────────────────────────── # Legt den Admin an. Danach ADMIN_PASSWORD leeren. +# Auch hier: ein $ muss $$ heissen (siehe DB_PASSWORD). ADMIN_USERNAME=admin ADMIN_PASSWORD=changeme_strong_admin_password