Commit Graph
81 Commits
Author SHA1 Message Date
Stefan HackerandClaude Opus 4.6 a445256d86 fix: Alle Rust-Warnings bereinigt
- unused variables: Underscore-Prefix (_real_path, _had_changes, _file_id)
- dead_code: #[allow(dead_code)] fuer zukuenftige Methoden
  (open_cloud_file, close_cloud_file, get_changes, LockResponse, SyncChangesResponse)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 02:02:53 +02:00
Stefan HackerandClaude Opus 4.6 0d1fc67287 fix: use std::path::Path Import fuer is_file_in_use
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:55:56 +02:00
Stefan HackerandClaude Opus 4.6 b606ec9a4a docs: CHANGELOG.md - komplette Projekthistorie
Von der ersten Zeile Code bis zum Desktop Sync Client.
9 Versionen, 70+ Commits, alles an einem Tag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:52:43 +02:00
Stefan HackerandClaude Opus 4.6 86545ca405 feat: Minimiert starten + kein Fenster-Popup bei .cloud Oeffnung
- .cloud Doppelklick oeffnet Datei im Hintergrund ohne das Client-
  Fenster aufzupoppen (war nervig)
- Neue Einstellung "Minimiert starten (direkt im System-Tray)"
  als Checkbox im Einstellungen-Bereich
- Wird in config.json gespeichert, bleibt bei Updates erhalten
- Bei aktiviertem Haken: Client startet unsichtbar im Tray,
  Sync laeuft im Hintergrund, Fenster nur per Tray-Doppelklick

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:50:09 +02:00
Stefan HackerandClaude Opus 4.6 e9638cc6ed fix: Lock verschwindet nicht mehr - Token-Refresh + laengerer Timeout
Problem: Lock verschwand nach 5 Minuten weil:
1. JWT-Token nach 15 Min ablief -> Heartbeat schlug still fehl
2. Server gab Lock nach 5 Min ohne Heartbeat frei

Fix Client:
- Token-Refresh alle 10 Minuten (vor dem 15-Min-Ablauf)
- Aktualisiert den Token in der shared API-Instanz
- Heartbeat nutzt immer den aktuellen Token

Fix Backend:
- Lock-Timeout von 5 auf 15 Minuten erhoeht
- Genug Puffer fuer Netzwerk-Probleme oder kurze Unterbrechungen

Timeline:
  0s    -> Lock + Heartbeat alle 10s
  600s  -> Token-Refresh
  900s  -> Lock wuerde erst jetzt ablaufen (15 Min ohne Heartbeat)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:45:52 +02:00
Stefan HackerandClaude Opus 4.6 b937351556 feat: Auto-Unlock wenn Datei geschlossen wird
Problem: Nach Oeffnen einer .cloud-Datei blieb die Sperre auf dem
Server bestehen, auch wenn Word/Excel geschlossen wurde.

Loesung: Hintergrund-Thread prueft alle 10 Sekunden ob geoeffnete
Dateien noch von einem Prozess benutzt werden:

Windows: Versucht exklusiven Schreibzugriff - wenn erfolgreich ist
  die Datei nicht mehr in Benutzung (Office gibt den Lock frei)
Linux/Mac: lsof prueft ob ein Prozess die Datei offen hat

Wenn Datei geschlossen:
1. Aenderungen werden zum Server hochgeladen
2. Server-Lock wird aufgehoben
3. .cloud Platzhalter wird neu erstellt (mit aktuellem Checksum)
4. Lokale Kopie wird geloescht
5. UI zeigt "Geschlossen + entsperrt: datei.cloud"

Tracking: opened_files HashMap speichert file_id -> Pfad + Cloud-Name
fuer alle via .cloud geoeffneten Dateien.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:44:40 +02:00
Stefan HackerandClaude Opus 4.6 4673423e2f fix: Sync vergleicht Timestamps - Server-Aenderungen nicht ueberschreiben
Problem: Wenn eine Datei auf dem Server geaendert wurde, hat der
Client sie trotzdem mit der lokalen (alten) Version ueberschrieben.
Der Sync hat nur Checksums verglichen aber nicht geprueft wer neuer ist.

Fix: Bei unterschiedlichen Checksums wird jetzt der Timestamp verglichen:
- Server neuer (updated_at > lokales modified) -> Download vom Server
- Lokal neuer (modified > Server updated_at) -> Upload zum Server
- Log zeigt "Server->Lokal" oder "Lokal->Server" statt nur "Aktualisiert"

Betrifft alle drei Sync-Methoden:
- sync_virtual (Offline-markierte Dateien)
- sync_upload_new (Virtual Mode Upload)
- sync_full_upload (Full Sync Upload)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:42:46 +02:00
Stefan HackerandClaude Opus 4.6 11fd11aa45 docs: README Desktop Sync Client komplett dokumentiert
- Features-Liste (Virtual Files, Multi-Sync, Offline, Locking, Tray etc.)
- Terminalserver-Tabelle (pro User eigene Instanz)
- Virtual Files vs. Full Sync Vergleichstabelle
- Einstellungen-Pfade pro OS
- Config bleibt bei Updates erhalten

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:30:08 +02:00
Stefan HackerandClaude Opus 4.6 b653f9657a fix: Single-Instance per User (Terminalserver-kompatibel)
Lock-File liegt in %APPDATA% (Windows) bzw ~/.config (Linux) -
das ist pro User verschieden. Auf Terminalservern kann jeder
User seine eigene Instanz haben.

Verbesserungen:
- Prueft ob der Prozess aus dem Lock-File noch lebt (PID-Check)
  statt nur ob die Datei existiert
- Windows: tasklist /FI "PID eq X"
- Linux: /proc/PID existiert?
- Stale Lock-Files (Prozess abgestuerzt) werden ueberschrieben
- Ohne .cloud Argument + andere Instanz laeuft -> sofort beenden
- Mit .cloud Argument + andere Instanz -> delegieren und beenden

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:28:39 +02:00
Stefan HackerandClaude Opus 4.6 4cc8de8a1a fix: Settings persistent (kein Keyring) + Single-Instance
Config-Persistenz:
- Passwort wird base64-kodiert in config.json gespeichert
  (statt OS-Keyring der beim Cross-Compile nicht funktioniert)
- Config-Pfad wird beim Laden/Speichern geloggt fuer Debugging
- Keyring-Dependency entfernt, base64 hinzugefuegt

Single-Instance:
- Lock-File in Config-Dir verhindert doppelte Instanz
- Wenn .cloud Datei doppelgeklickt wird und Client laeuft:
  Pfad wird in open_request.txt geschrieben und 2. Instanz beendet sich
- Laufende Instanz pollt open_request.txt und oeffnet die Datei
- Fenster wird automatisch in den Vordergrund geholt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:27:03 +02:00
Stefan HackerandClaude Opus 4.6 c354682905 fix: Tray-Icon API kompatibel (kein Image::from_bytes)
Nutzt default_window_icon() statt Image::from_bytes das in
dieser Tauri-Version nicht existiert.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:15:02 +02:00
Stefan HackerandClaude Opus 4.6 ac5a0a3367 feat: Settings persistent + Auto-Login + Installer Update-Modus
Settings-Persistenz:
- Config wird in OS-AppData gespeichert
  (Windows: %APPDATA%/MiniCloud Sync/config.json,
   Linux: ~/.config/MiniCloud Sync/config.json,
   Mac: ~/Library/Application Support/MiniCloud Sync/config.json)
- Gespeichert werden: Server-URL, Username, Sync-Pfade
- Passwort wird im OS-Keychain gespeichert (Windows Credential Manager,
  macOS Keychain, Linux Secret Service) - nicht in der Config-Datei

Auto-Login:
- Beim Start wird gespeicherte Config geladen
- Wenn Credentials im Keychain vorhanden: automatischer Login
- Wenn Sync-Pfade konfiguriert: Sync startet sofort automatisch
- Bei Fehler: Login-Screen mit vorausgefuellten Feldern

Config ueberlebt Updates:
- Config liegt ausserhalb des Installationsverzeichnisses
- NSIS-Installer ueberschreibt nur App-Dateien, nicht AppData
- installMode: "both" erlaubt per-User und per-Machine Installation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:11:42 +02:00
Stefan HackerandClaude Opus 4.6 81574c8991 fix: Virtual Mode laedt neue lokale Dateien jetzt hoch
Problem: Im Virtual Mode wurden nur .cloud Platzhalter fuer
Server-Dateien erstellt, aber neue lokale Dateien wurden nie
hochgeladen. Der Watcher hat die Aenderung erkannt aber der
Sync hat sie ignoriert.

Fix: sync_upload_new() wird jetzt auch im Virtual Mode aufgerufen.
Scannt den lokalen Ordner nach Dateien die auf dem Server nicht
existieren und laedt sie hoch. Auch geaenderte lokale Dateien
(Checksum-Vergleich) werden aktualisiert. Gesperrte Dateien
werden zurueckgehalten.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:04:03 +02:00
Stefan HackerandClaude Opus 4.6 607d18a7e2 feat: Lokaler Datei-Browser mit Offline-Markierung + Kontextmenue
Datei-Browser im Client:
- Zeigt lokalen Sync-Ordner mit allen Dateien an
- Ordner navigierbar mit Breadcrumb
- Status pro Datei: ☁ Cloud (Platzhalter) / 📄 Offline (echte Datei)
- Badges: blaues "Cloud" oder gruenes "Offline"
- Cloud-Dateien zeigen Originalgroesse aus .cloud-Metadaten
- Aktualisiert sich automatisch nach jedem Sync

Rechtsklick-Kontextmenue:
- .cloud Datei: "Oeffnen (herunterladen)" + "Offline verfuegbar machen"
- Echte Datei: "Nicht mehr offline (Platzhalter)"
- Doppelklick auf Ordner = navigieren
- Doppelklick auf .cloud = herunterladen + oeffnen

Rust-Backend:
- browse_sync_folder: Listet lokale Dateien mit Status auf
  (is_cloud, is_offline, cloud_size aus JSON-Metadaten)
- Sortierung: Ordner zuerst, dann alphabetisch

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 01:02:21 +02:00
Stefan HackerandClaude Opus 4.6 adaa19a1ef fix: Durchsuchen-Button, Tray-Icon, Minimize statt Close, .cloud Handler
1. Durchsuchen-Button: dialog:allow-open Permission in capabilities
2. Tray-Icon: Nutzt das App-Icon (32x32.png) statt leer
3. Close = Minimize: Fenster wird versteckt statt App beendet,
   Doppelklick auf Tray-Icon oeffnet wieder
4. .cloud Datei-Handler:
   - fileAssociations in tauri.conf.json registriert .cloud Extension
   - NSIS-Installer registriert den Handler automatisch
   - Doppelklick auf .cloud -> App startet, laedt Datei runter,
     oeffnet mit Standard-App (Word/Excel/etc.)
   - Wenn App laeuft: Event wird emitted, Frontend verarbeitet es

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:57:18 +02:00
Stefan HackerandClaude Opus 4.6 505545f26c feat: Watcher triggert sofort Sync + Offline-Markierung pro Datei
Sofort-Sync statt 30s-Polling:
- Filesystem-Watcher erkennt lokale Aenderungen sofort
- 3 Sekunden Debounce (wartet ob noch mehr kommt)
- Dann sofortiger Sync-Trigger statt auf den naechsten 30s-Zyklus zu warten
- .cloud-Dateien werden vom Watcher ignoriert (kein Loop)
- Fallback: alle 60s Sync auch ohne Aenderungen (Server-Aenderungen holen)
- UI zeigt "→ Sync ausgeloest" bei Watcher-Trigger

Offline-Markierung:
- mark_offline: .cloud -> echte Datei runterladen, bleibt permanent lokal
- unmark_offline: echte Datei -> zurueck zu .cloud Platzhalter
- Offline-Dateien werden bei jedem Sync automatisch aktualisiert
  (Checksum-Vergleich in sync_virtual)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:44:57 +02:00
Stefan HackerandClaude Opus 4.6 e32a64ba83 fix: fehlende npm-Dependencies fuer Tauri-Plugins (dialog, notification)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:40:25 +02:00
Stefan HackerandClaude Opus 4.6 16d514f7f1 feat: Virtual Files, Multi-Sync-Pfade, Full Sync, Ordner-Dialog
Virtual Files System:
- .cloud Platzhalter-Dateien (JSON mit ID, Name, Groesse, Checksum)
- 0 Bytes Speicherverbrauch pro Datei
- Doppelklick auf .cloud -> Download + Oeffnen mit Standard-App + Lock
- Nach Schliessen: Sync zurueck, lokale Kopie entfernen, .cloud neu
- Offline-Markierung: Echte Dateien bleiben lokal (kein .cloud)
- Server-Dateien loeschen -> .cloud wird automatisch entfernt

Multi-Sync-Pfade (wie Nextcloud):
- Beliebig viele Server-Ordner auf lokale Ordner mappen
- z.B. /Projekte/2026 -> ~/Projekte oder /Shared/Team -> ~/Team
- Freigegebene Ordner von anderen Benutzern sync-bar
- Jeder Pfad hat eigenen Modus (Virtual oder Full)
- Hinzufuegen/Entfernen/Modus wechseln in der UI

Full Sync:
- Pro Sync-Pfad waehlbar: Virtual oder Full
- Full = alle Dateien lokal spiegeln (bidirektional)
- Virtual = .cloud Platzhalter (Standard)
- Klick auf Modus-Badge zum Umschalten

Ordner-Dialog:
- "Durchsuchen..." Button oeffnet nativen Ordner-Auswahl-Dialog
- Server-Ordner per Dropdown aus Dateibaum waehlen
- Ordner werden automatisch erstellt wenn noetig

UI:
- Sync-Pfade als Karten: ☁ /Server/Pfad → 📁 /Lokaler/Pfad
- Modus-Badge (Virtual/Full) mit Klick zum Wechseln
- Tray-Menue: "Jetzt synchronisieren" Eintrag

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:34:03 +02:00
Stefan HackerandClaude Opus 4.6 4662286959 fix: Windows Build laedt Setup-Installer hoch statt nackte .exe
Die nackte .exe braucht WebView2 separat installiert.
Der NSIS-Setup-Installer (nsis/*setup*.exe) installiert WebView2
automatisch mit. Jetzt wird der Setup bevorzugt hochgeladen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:09:32 +02:00
Stefan HackerandClaude Opus 4.6 ba7e541260 docs: Docker aufraeumen - Speicher freigeben Anleitung
docker system prune, image prune, builder prune, system df

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:02:54 +02:00
Stefan HackerandClaude Opus 4.6 60e9f2699e docs: Docker-Cache loeschen Anleitung in README
build --no-cache, Image loeschen, Browser-Cache Hinweis

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:01:02 +02:00
Stefan HackerandClaude Opus 4.6 96d82967fc fix: build.sh zeigt klare Fehlermeldung bei falschem Upload-Token
403 -> Erklaerung dass BUILD_UPLOAD_TOKEN der SECRET_KEY vom Server sein muss
000 -> Server nicht erreichbar
Sonstige -> HTTP-Code + Response-Body

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:00:33 +02:00
Stefan HackerandClaude Opus 4.6 29cc00e284 fix: Client-Upload akzeptiert SECRET_KEY oder JWT_SECRET_KEY + Download in Settings
Upload-Auth:
- Akzeptiert jetzt sowohl SECRET_KEY als auch JWT_SECRET_KEY
  (BUILD_UPLOAD_TOKEN in Entwicklungs-.env kann einer von beiden sein)

Settings-View:
- Zeigt verfuegbare Desktop/Mobile Clients zum Download an
  (nur wenn mindestens ein Client vorhanden)
- Pro Client: Name, Dateiname, Download-Button

.env.example:
- Klarere Kommentare: "SECRET_KEY oder JWT_SECRET_KEY des Zielservers"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:58:54 +02:00
Stefan HackerandClaude Opus 4.6 9391a58683 fix: build-output/ in .gitignore + aus Git entfernt
Binaries gehoeren nicht ins Repository.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:55:09 +02:00
Stefan HackerandClaude Opus 4.6 714ce1ae53 feat: Desktop-Client komplett - Auto-Sync, Watcher, Locking, Tray
Alles eingebunden was vorher nur als unused code existierte:

Auto-Sync:
- Nach erstem Sync laeuft alle 30s ein Delta-Sync im Hintergrund
- Status-Badge zeigt live: Synchronisiert / Synchronisiere... / Fehler
- Sync-Protokoll mit Timestamps

File-Watcher:
- Ueberwacht den Sync-Ordner auf lokale Aenderungen (Erstellt/Geaendert/Geloescht)
- Aenderungen werden im UI unter "Lokale Aenderungen" angezeigt
- Filtert temp/hidden files automatisch

File-Locking:
- lock_file_cmd / unlock_file_cmd Tauri-Kommandos
- Heartbeat-Thread sendet alle 60s Heartbeat fuer gesperrte Dateien
- locked_files Liste im State

System-Tray:
- Tray-Icon mit "Mini-Cloud Sync" Tooltip
- Rechtsklick-Menue: Oeffnen / Beenden
- "Oeffnen" zeigt das Hauptfenster

UI:
- Status-Badge mit Farbe (gruen=synced, orange=syncing, rot=error)
- Spinning-Icon waehrend Sync
- "Auto-Sync aktiv" Hinweis nach erstem Sync
- Sync-Ordner wird nach Start gesperrt (nicht mehr aenderbar)
- Lokale Aenderungen und Sync-Log mit Timestamps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:54:54 +02:00
Stefan HackerandClaude Opus 4.6 8342cbfa17 fix: main.rs lib-Name auf minicloud_sync_lib korrigiert
War noch tauri_app_lib vom Template, muss minicloud_sync_lib heissen
(wie in Cargo.toml definiert).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:47:18 +02:00
Stefan HackerandClaude Opus 4.6 10e6211820 fix: Rust MutexGuard ueber await - delta_sync Send-Fehler
MutexGuard wird jetzt vor dem .await gedroppt (take + put back),
damit der Future Send-kompatibel ist wie Tauri es erfordert.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:42:28 +02:00
Stefan HackerandClaude Opus 4.6 ec3d4866e0 refactor: Build-Upload nutzt SECRET_KEY + Doku klargestellt
- Backend: Upload-Auth prueft SECRET_KEY statt eigenen Token
  (ein Token weniger zu verwalten)
- BUILD_UPLOAD_TOKEN in Entwicklungs-.env = SECRET_KEY vom Server
- .env.example: Klarer Kommentar dass CLOUD_URL + BUILD_UPLOAD_TOKEN
  NUR auf der Entwicklungsmaschine gesetzt werden, nicht auf dem Server
- README: Desktop Sync Client Abschnitt mit Build-Anleitung und
  Auto-Upload-Erklaerung

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:41:22 +02:00
Stefan HackerandClaude Opus 4.6 9a6aa7aadc feat: Client-Download-System + Auto-Upload nach Build
Backend:
- GET /api/clients - Verfuegbare Clients auflisten (oeffentlich)
- GET /api/clients/<platform>/download - Client herunterladen (oeffentlich)
- POST /api/clients/<platform>/upload - Build hochladen (BUILD_UPLOAD_TOKEN)
- Alte Version wird automatisch bei neuem Upload ersetzt
- Plattformen: linux, windows, mac, android, ios

Frontend:
- /clients - Download-Seite mit Grid aller verfuegbaren Clients
- Login-Seite zeigt "Desktop & Mobile Clients herunterladen" Link
  wenn mindestens ein Client verfuegbar ist

build.sh:
- Nach jedem Build wird der Client automatisch auf CLOUD_URL
  hochgeladen (wenn CLOUD_URL + BUILD_UPLOAD_TOKEN in .env gesetzt)
- Bestes Format pro Plattform: AppImage > .deb > Binary (Linux),
  .msi > .exe (Windows), .dmg (Mac), .apk (Android), .ipa (iOS)

.env.example:
- CLOUD_URL: Oeffentliche URL der Cloud-Instanz
- BUILD_UPLOAD_TOKEN: Auth-Token fuer Build-Upload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:39:51 +02:00
Stefan HackerandClaude Opus 4.6 3ed5adc1e8 fix: sudo vor allen docker-Befehlen im build.sh
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:31:30 +02:00
Stefan HackerandClaude Opus 4.6 48a46cbc79 feat: Build-Script + Docker-Build fuer alle Plattformen
build.sh - baut Clients via Docker (kein lokales Setup noetig):
  ./build.sh linux        # Linux Desktop (.deb + .AppImage)
  ./build.sh windows      # Windows Desktop (.msi + .exe) Cross-Compile
  ./build.sh mac          # macOS Desktop (.dmg) - nur auf macOS
  ./build.sh android      # Android App (.apk) via Docker
  ./build.sh ios          # iOS App (.ipa) - nur auf macOS
  ./build.sh all-desktop  # Linux + Windows zusammen
  ./build.sh clean        # Build-Cache loeschen

Dockerfile.build: Multi-stage Container mit Rust, Node.js, Tauri-Deps,
  Windows Cross-Compile Tools (mingw-w64)

Output landet in build-output/ (gitignored)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:29:58 +02:00
Stefan HackerandClaude Opus 4.6 06ad65dbb3 feat: Desktop Sync Client (Tauri) - Grundgeruest
Tauri 2 Desktop-Client mit:

Rust-Backend:
- MiniCloudApi: Login, Token-Refresh, Upload, Download, Sync-Tree,
  Sync-Changes, File-Locking (Lock/Unlock/Heartbeat)
- SyncEngine: Full-Sync (Server-Tree vs. lokales Dateisystem),
  Delta-Sync (nur Aenderungen seit letztem Sync), bidirektionaler
  Abgleich mit SHA-256 Checksummen, Ordner-Erstellung,
  Lock-Status-Pruefung vor Upload, Konflikt-Erkennung
- FileWatcher: Filesystem-Watcher (notify crate) fuer Echtzeit-
  Erkennung lokaler Aenderungen, filtert temp/hidden files

Vue-Frontend:
- Login-Screen: Server-URL, Benutzername, Passwort
- Main-Screen: Sync-Ordner setzen, Sync starten, Dateiliste mit
  Lock-Status, Sync-Protokoll
- Dark-Mode Support

Tauri-Kommandos: login, set_sync_dir, start_sync, delta_sync,
  get_status, get_file_tree

Zum Bauen (Linux):
  sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev
  cd clients/desktop && npm install && npm run tauri build

Windows/Mac: Tauri Voraussetzungen installieren, dann gleicher Befehl

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:26:57 +02:00
Stefan HackerandClaude Opus 4.6 748537b9f5 feat: File Locking System (Ein-/Auschecken) + Konflikt-Email
Backend - FileLock Model + API:
- POST /files/<id>/lock - Datei auschecken (sperren)
- POST /files/<id>/unlock - Datei einchecken (entsperren)
- POST /files/<id>/heartbeat - "Datei noch offen" (alle 60s)
- GET /files/<id>/lock-status - Sperrstatus abfragen
- GET /files/locks - Alle aktiven Sperren auflisten
- Auto-Unlock: Kein Heartbeat seit 5 Min -> Sperre wird freigegeben
- 423 Locked wenn bereits von anderem User gesperrt
- Admin kann fremde Sperren aufheben

Dateiliste + Sync-API:
- Lock-Info (locked, locked_by, locked_at) pro Datei mitgeliefert
- Sync-Tree enthaelt Lock-Status fuer Desktop/Mobile-Clients

Web-UI:
- Schloss-Icon mit Benutzername bei gesperrten Dateien
- Tooltip: "Ausgecheckt von Adam seit 14:30"
- Gesperrte Dateien: "Oeffnen nicht moeglich" Toast-Meldung
  (eigene Sperren sind erlaubt)

Konflikt-Email an Admin:
- Wer hat die Konflikt-Kopie erstellt (Name + Email)
- Welche Datei (Name + Ordnerpfad)
- Name der Konflikt-Kopie
- Von wem gesperrt (Name + Email + seit wann)
- Erklaerungstext was passiert ist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:20:55 +02:00
Stefan HackerandClaude Opus 4.6 33156f9431 feat: OnlyOffice Force-Save bei Ctrl+S + private IP erlauben
- forcesavetype in Editor-Config: Ctrl+S speichert sofort zurueck
  zum Server (statt erst beim Schliessen des Dokuments)
- ALLOW_PRIVATE_IP_ADDRESS + ALLOW_META_IP_ADDRESS fuer OnlyOffice
  damit Callbacks an interne Docker-IPs funktionieren

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:54:31 +02:00
Stefan HackerandClaude Opus 4.6 5f79ebe9b0 fix: OnlyOffice/Preview zeigt immer aktuelle Version (kein Cache)
Drei Cache-Ebenen gefixt:
- Vue Router: :key=fullPath erzwingt Komponenten-Neuaufbau bei
  jeder Navigation (kein Wiederverwenden alter Instanzen)
- Frontend: Cache-Bust Parameter an Preview + OnlyOffice API-Calls
- Backend: No-Cache Headers (Cache-Control, Pragma) auf Preview-Endpunkt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:50:33 +02:00
Stefan HackerandClaude Opus 4.6 916971fc1b fix: OnlyOffice Cache - jedes Oeffnen laedt frische Version
Document-Key nutzt jetzt Timestamp statt Checksum, damit OnlyOffice
bei jedem Oeffnen die aktuelle Version vom Server laedt statt eine
gecachte alte Version anzuzeigen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:47:17 +02:00
Stefan HackerandClaude Opus 4.6 bb73a8130a fix: Doppelter Route-Dekorator auf oo_download entfernt
Der @api_bp.route('/files/onlyoffice-callback') Dekorator war
versehentlich auf oo_download statt onlyoffice_callback gelandet.
Flask routete dadurch alle Callback-POSTs an oo_download, die dann
mit 'missing access_key argument' crashte (500 Error).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:41:35 +02:00
Stefan HackerandClaude Opus 4.6 9d138ecf1d fix: OnlyOffice Callback komplett neu - robust gegen 500 Errors
- Gesamter Callback in try/except gewrapped (gibt immer error:0
  zurueck, damit OnlyOffice nicht endlos retryt)
- JWT Body-Decoding mit graceful fallback auf Raw-Daten
- JWT-Header-Validierung entfernt (verursachte den 500 Crash)
- Download ohne extra JWT-Header (OnlyOffice-interne URLs
  brauchen das nicht)
- Ausfuehrliches Logging: Status, Key, Dateiname, Groesse
- Saubere Imports am Anfang der Funktion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:34:24 +02:00
Stefan HackerandClaude Opus 4.6 9d1f4e117c fix: OnlyOffice Callback JWT-Validierung + Speichern
Problem: OnlyOffice sendete JWT-Token im Callback-Request und im
Body, unser Endpoint hat das ignoriert -> Speichern schlug fehl.

Fix:
- Callback validiert OnlyOffice JWT aus Authorization-Header
- Callback entpackt JWT-wrapped Body (OnlyOffice wraps den Body
  in einen JWT-Token wenn JWT_ENABLED=true)
- Download der gespeicherten Datei sendet JWT-Header mit
- Besseres Error-Logging mit Traceback

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:28:34 +02:00
Stefan HackerandClaude Opus 4.6 1f9b87900c fix: Dedizierter OnlyOffice Download-Endpunkt ohne JWT-Auth
Problem: OnlyOffice konnte Dateien nicht herunterladen weil unser
token_required-Decorator den Request ablehnte - OnlyOffice sendet
eigene Header die mit unserem JWT-System kollidieren.

Loesung: Eigener Endpunkt GET /files/oo-download/<access_key>
- Kein JWT noetig, stattdessen Einmal-Schluessel
- Schluessel wird beim Oeffnen des Editors generiert und in der DB gespeichert
- Schluessel enthaelt file_id + user_id, wird beim Download validiert
- OnlyOffice ruft diesen Endpunkt intern auf (http://minicloud:5000)
- Kein Token in der URL, keine JWT-Konflikte

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:24:09 +02:00
Stefan HackerandClaude Opus 4.6 c3c0610750 fix: OnlyOffice nutzt internes Docker-Netzwerk + langlebigen Token
Problem: OnlyOffice versuchte Dateien ueber die oeffentliche URL
herunterzuladen (http://selftestcloud...) und bekam 401 weil der
Access-Token nach 15 Min. ablief.

Fix:
- Download-URL und Callback-URL nutzen jetzt die interne Docker-URL
  (http://minicloud:5000) statt die oeffentliche URL
- Eigener 24h-Token fuer OnlyOffice Datei-Zugriff (statt des
  kurzlebigen User-Access-Tokens)
- ONLYOFFICE_INTERNAL_URL konfigurierbar (Default: http://minicloud:5000)

So bleibt der gesamte Dateizugriff zwischen OnlyOffice und Mini-Cloud
im Docker-Netzwerk - schneller und kein externer Roundtrip.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:19:30 +02:00
Stefan HackerandClaude Opus 4.6 35fddbfcbc docs: README OnlyOffice-Abschnitt aktualisiert
- Kein ONLYOFFICE_JWT_SECRET mehr, nutzt JWT_SECRET_KEY automatisch
- Nur noch ONLYOFFICE_URL in .env setzen
- Eigene Subdomain mit HTTPS als Pflicht beschrieben
- Schritte vereinfacht (4 statt 5)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:10:54 +02:00
Stefan HackerandClaude Opus 4.6 15211509a6 simplify: OnlyOffice nutzt JWT_SECRET_KEY, kein extra Secret
- OnlyOffice und Mini-Cloud teilen sich den gleichen JWT_SECRET_KEY
- ONLYOFFICE_JWT_SECRET komplett entfernt (aus .env, docker-compose, Backend, Frontend)
- docker-compose: OnlyOffice liest JWT_SECRET=${JWT_SECRET_KEY}
- In .env nur noch ONLYOFFICE_URL setzen, fertig
- Admin-GUI zeigt: URL + "JWT nutzt JWT_SECRET_KEY aus .env"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:10:06 +02:00
Stefan HackerandClaude Opus 4.6 0dbeef7cd9 refactor: OnlyOffice Konfiguration nur ueber .env, nicht Admin-GUI
OnlyOffice URL und JWT Secret kommen jetzt ausschliesslich aus der
.env Datei (Umgebungsvariablen), nicht mehr aus der Admin-GUI:
- ONLYOFFICE_URL und ONLYOFFICE_JWT_SECRET in .env setzen
- docker-compose liest das gleiche Secret fuer den OnlyOffice-Container
- Eine Quelle der Wahrheit, kein Sync zwischen .env und DB noetig

Admin-GUI zeigt jetzt nur noch den Status an:
- Konfiguriert / Nicht konfiguriert (Tag)
- Aktuelle URL
- JWT Secret gesetzt / Fehlt (Tag)
- Setup-Anleitung mit .env Beispiel

Behebt: "Sicherheitstoken nicht korrekt" wenn OnlyOffice laeuft
aber JWT Secret nicht uebereinstimmt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:08:07 +02:00
Stefan HackerandClaude Opus 4.6 5bf98302e3 fix: DATABASE_PATH und UPLOAD_PATH aus .env entfernt
Pfade werden jetzt automatisch gesetzt und nicht mehr in .env
ueberschrieben, was den Bug verursacht hatte:
- Docker: Dockerfile setzt /app/data/ als ENV-Default
- Entwicklung: Config nutzt CWD/data/ als Default

.env.example erklaert das mit Kommentar.
Optionale manuelle Pfade bleiben als auskommentierte Zeilen.

Auf dem Server: DATABASE_PATH und UPLOAD_PATH aus .env loeschen
(oder auskommentieren), dann docker-compose up --build -d

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:58:58 +02:00
Stefan HackerandClaude Opus 4.6 97cb4c7748 fix: Datenbank-Pfad in Docker - relative Pfade aus .env falsch aufgeloest
Problem: Nach Umstellung auf env_file in docker-compose wurden die
relativen Pfade (./data/minicloud.db) aus .env falsch aufgeloest.
basedir zeigte auf / statt /app, dadurch wurde eine neue leere DB
unter /data/ erstellt statt die bestehende unter /app/data/ zu nutzen.
Ergebnis: Alle User weg, Login unmoeglich.

Fix:
- config.py: _resolve_path nutzt Path.cwd() fuer relative Pfade
  (in Docker CWD=/app, in Dev CWD=backend/)
- .env.example: Absolute Docker-Pfade als Default
  (/app/data/minicloud.db statt ./data/minicloud.db)
  mit Kommentar fuer Entwicklungsumgebung

Auf dem Server muss die .env angepasst werden:
  DATABASE_PATH=/app/data/minicloud.db
  UPLOAD_PATH=/app/data/files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:53:43 +02:00
Stefan HackerandClaude Opus 4.6 c23205d2a6 feat: OnlyOffice in docker-compose aktiviert
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:43:37 +02:00
Stefan HackerandClaude Opus 4.6 67790af95e fix: OnlyOffice Port-Mapping 8080:80 in docker-compose ergaenzt
nginx braucht Zugriff auf den OnlyOffice-Container um ihn per
HTTPS nach aussen weiterzuleiten (proxy_pass http://127.0.0.1:8080).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:42:16 +02:00
Stefan HackerandClaude Opus 4.6 3185b2d41c docs: .env.example + docker-compose + README komplett aktualisiert
- .env.example: OnlyOffice-Variablen (URL + JWT_SECRET) hinzugefuegt,
  FRONTEND_URL auf HTTPS-Beispiel geaendert
- docker-compose.yml: Nutzt env_file statt einzelner Variablen,
  alle Secrets kommen aus .env (eine Quelle der Wahrheit)
- README.md komplett ueberarbeitet:
  - Alle Features dokumentiert (Papierkorb, Share-Link-Typen,
    Drag&Drop, OnlyOffice, SFTP-Backup, Benachrichtigungen etc.)
  - Docker + nginx Reverse-Proxy Beispiel mit Let's Encrypt
  - OnlyOffice Setup-Anleitung (docker-compose + nginx + .env)
  - Alle Verwendungs-Abschnitte aktualisiert
  - Administration dokumentiert

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:27:13 +02:00
Stefan HackerandClaude Opus 4.6 fca2bc2d47 fix: OnlyOffice Docker-Setup ohne Port-Mapping + nginx-Beispielconfig
- docker-compose.yml: Kein ports-Mapping fuer OnlyOffice mehr
  (Zugriff nur ueber nginx mit HTTPS, nicht direkt ueber Port 8080)
- nginx.example.conf: Komplette Beispielkonfiguration fuer
  cloud.example.com + office.example.com mit Let's Encrypt
  - Unbegrenztes Upload-Limit (client_max_body_size 0)
  - CalDAV/CardDAV spezielle Location
  - WebSocket-Support vorbereitet
  - HTTP->HTTPS Redirect
- Admin-UI: Setup-Anleitung aktualisiert - erklaert nginx + HTTPS +
  Let's Encrypt Schritte, Hinweis dass die oeffentliche HTTPS-URL
  eingetragen werden muss (nicht die interne Docker-URL)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:23:31 +02:00
Stefan HackerandClaude Opus 4.6 216445d41b feat: OnlyOffice Document Server Integration + Preview ohne neuen Tab
OnlyOffice Integration:
- DOCX, XLSX, PPTX nativ im Browser bearbeiten (wie Google Docs)
- Automatische Erkennung: Wenn OnlyOffice konfiguriert ist, wird der
  vollwertige Editor geladen, sonst die einfache Vorschau als Fallback
- Backend: WOPI-aehnliche Endpunkte
  - GET /files/<id>/onlyoffice-config - Editor-Konfiguration
  - POST /files/onlyoffice-callback - Speicher-Callback von OnlyOffice
  - GET /files/onlyoffice-status - Verfuegbarkeits-Check
- JWT-Signierung fuer sichere Kommunikation mit OnlyOffice
- Dokument-Key basiert auf file_id + checksum (Cache-Invalidierung)

Admin-Einstellungen:
- OnlyOffice URL + JWT Secret konfigurierbar
- Setup-Anleitung direkt in der UI (docker-compose auskommentieren)

docker-compose.yml:
- OnlyOffice Document Server als optionaler Service (auskommentiert)
- Einfach auskommentieren fuer volle Office-Bearbeitung

Preview:
- Oeffnet sich jetzt innerhalb der App (kein neuer Tab)
- Zurueck-Button in der Toolbar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:19:17 +02:00
Stefan HackerandClaude Opus 4.6 a2ded7f97c feat: Office-Preview im neuen Tab + DOCX/XLSX/Text bearbeitbar
Preview-System komplett ueberarbeitet:
- Neuer Tab: Doppelklick oder Auge-Icon oeffnet Vorschau im neuen Tab
- Dedizierte PreviewView mit Toolbar (Zurueck, Bearbeiten, Speichern, Download)
- Token wird als Query-Parameter an Preview/Download-URLs angehaengt (kein 404 mehr)

Unterstuetzte Formate:
- PDF: Inline-Anzeige im iFrame
- Bilder: Zentrierte Anzeige mit Schatten
- DOCX: HTML-Darstellung mit Formatierung (Headings, Bold, Italic, Tabellen)
- XLSX: Tabellen-Ansicht mit Sheet-Tabs
- PPTX: Folien-Navigation (vor/zurueck)
- Text/Code: Monospace mit Syntax

Bearbeitung (neu!):
- DOCX: ContentEditable-Editor, Bold/Italic/Headings bleiben erhalten,
  Speichern schreibt zurueck als .docx (python-docx)
- XLSX: Direkt in der Tabelle bearbeiten (Zellen anklicken),
  Speichern schreibt zurueck als .xlsx (openpyxl)
- Text/Code: Textarea-Editor, Speichern als UTF-8

Backend: POST /files/<id>/save mit type-spezifischer Konvertierung
- html -> DOCX (Headings, Bold/Italic/Underline erhalten)
- spreadsheet -> XLSX (Zahlen werden automatisch konvertiert)
- text -> direkt als Datei

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:07:59 +02:00
Stefan HackerandClaude Opus 4.6 67118a34fd fix: Share-View Loeschen nutzt jetzt Papierkorb statt hartem Delete
- share_delete_file nutzt _trash_recursive() statt db.session.delete()
- Geloeschte Dateien aus Share-Links landen im Papierkorb des Eigentümers
- Share-Dateiliste filtert getrashte Dateien aus (is_trashed=False)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:53:47 +02:00
Stefan HackerandClaude Opus 4.6 82f3091f2e feat: Papierkorb + Bestaetigungsdialoge bei allen Loeschaktionen
Papierkorb:
- Dateien/Ordner werden beim Loeschen in den Papierkorb verschoben
  (Soft-Delete) statt sofort geloescht
- Papierkorb-Seite in der Sidebar mit Tabelle aller geloeschten Elemente
- Pro Element: Wiederherstellen (am Originalort) oder endgueltig loeschen
- "Papierkorb leeren" Button loescht alles unwiderruflich
- Backend: is_trashed, trashed_at, original_parent_id Felder im File-Model
- Getrashte Dateien erscheinen nicht in der normalen Dateiliste

Bestaetigungsdialoge (vorher fehlend):
- Kontakte: "Moechtest du XY wirklich loeschen?"
- Kalender Events: Bestaetigung vor dem Loeschen
- Kalender: Bestaetigung vor dem Loeschen (mit Hinweis auf Events)
- E-Mail Nachrichten: Bestaetigung mit Betreff-Vorschau
- Share-Link Dateien: Bestaetigung beim Loeschen aus geteiltem Ordner
- Admin SFTP-Backup-Ziele: Bestaetigung
- Admin Email-Konten: Bestaetigung

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:50:19 +02:00
Stefan HackerandClaude Opus 4.6 1ee80e650d fix: Download Token-Fehler - Token als Query-Parameter unterstuetzen
Problem: window.location.href sendet keinen Authorization-Header,
daher scheiterten alle direkten Downloads (Dateien + Ordner-ZIP)
mit 'Token fehlt'.

Loesung:
- Backend: token_required akzeptiert jetzt auch ?token=... als
  Query-Parameter (Fallback wenn kein Authorization-Header)
- Frontend: downloadUrl() haengt den Access-Token automatisch als
  Query-Parameter an die Download-URL an

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:39:58 +02:00
Stefan HackerandClaude Opus 4.6 ed1a619ad1 fix: ZIP-Download Icon - pi-box statt pi-file-zip (existiert nicht)
pi-file-zip gibt es in PrimeIcons nicht, daher wurde kein Icon
angezeigt. Ersetzt durch pi-box in Datei-Browser und Share-View.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:36:42 +02:00
Stefan HackerandClaude Opus 4.6 4b487974c6 fix: ZIP-Download, Share-Status live aktualisieren, Ordner-ZIP bei Share-Links
ZIP-Download fix:
- window.location.href statt a.download fuer API-Downloads
  (a.download funktioniert nicht mit authentifizierten API-Routen)

Share-Status live:
- Dateiliste wird nach jeder Share-Aenderung automatisch neu geladen
  (Link erstellen, Link loeschen, Benutzer-Freigabe setzen/entfernen)
- Gruenes Share-Icon aktualisiert sich sofort ohne F5

Ordner-ZIP bei Share-Links:
- "Ganzen Ordner als ZIP herunterladen" Button bei read/write Ordner-Shares
- Backend: GET /share/<token>/download-zip mit Passwort + Ablauf-Check
- Benachrichtigung an Ersteller bei ZIP-Download

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:35:30 +02:00
Stefan HackerandClaude Opus 4.6 1a831bfb04 feat: Ordner als ZIP herunterladen + Share-Status visuell anzeigen
Ordner-Download:
- Ordner koennen jetzt als ZIP heruntergeladen werden (rekursiv
  mit allen Unterordnern und Dateien)
- ZIP-Icon statt Download-Icon bei Ordnern in der Dateiliste
- Backend erstellt ZIP mit ZIP_DEFLATED und allowZip64 fuer grosse Ordner

Share-Status visuell:
- Share-Button zeigt gruenes Personen-Icon (pi-users) wenn die Datei/
  der Ordner bereits Freigaben hat (Links oder Benutzer-Berechtigungen)
- Normales Share-Icon (pi-share-alt) wenn keine Freigaben existieren
- Backend liefert has_shares und has_permissions pro Datei mit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:28:10 +02:00
Stefan HackerandClaude Opus 4.6 6515b3a256 feat: Unterordner-Navigation in Ordner-Freigaben
Geteilte Ordner koennen jetzt komplett durchnavigiert werden:

- Klick auf einen Unterordner oeffnet dessen Inhalt
- Breadcrumb-Navigation: Root > Unterordner > Unter-Unterordner
  mit Klick zurueck auf jede Ebene
- Ordner-Zeilen haben Hover-Effekt und Cursor-Pointer

Backend:
- GET /share/<token>/files?parent_id=X - Unterordner auflisten
- Sicherheitspruefung: parent_id muss innerhalb des geteilten
  Ordners liegen (_is_inside_shared_folder traversiert den Baum)
- Breadcrumb wird serverseitig berechnet
- Download + Delete erlauben jetzt Dateien in jeder Tiefe
  (nicht nur direkte Kinder)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:17:35 +02:00
Stefan HackerandClaude Opus 4.6 7a26788ad2 feat: Ordner-Freigaben zeigen Dateiliste + Download/Loeschen
Share-Links fuer Ordner verhalten sich jetzt je nach Berechtigung:

read (Nur Lesen):
- Zeigt alle Dateien im Ordner mit Name, Groesse, Typ
- Download-Button pro Datei
- Kein Upload, kein Loeschen

write (Lesen+Schreiben):
- Zeigt alle Dateien im Ordner
- Download-Button pro Datei
- Loeschen-Button pro Datei
- Upload-Zone (Drag & Drop + Button)
- Nach Upload wird Dateiliste automatisch aktualisiert

upload_only (Nur Upload):
- Kein Dateilisting, kein Ordnername sichtbar
- Nur Upload-Zone

Backend-Endpunkte:
- GET /share/<token>/files - Dateien im geteilten Ordner auflisten
- GET /share/<token>/files/<id>/download - Einzeldatei herunterladen
- DELETE /share/<token>/files/<id> - Datei loeschen (nur write)
- Alle Endpunkte pruefen Passwort, Ablaufdatum und Berechtigung
- Dateien muessen direkte Kinder des geteilten Ordners sein (kein Ausbruch)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:09:58 +02:00
Stefan HackerandClaude Opus 4.6 38d6acb1a1 fix: Auto-Migrate fuer fehlende DB-Spalten beim App-Start
Behebt 500 Internal Server Error beim Erstellen von Share-Links
auf bestehenden Datenbanken, denen die neue 'permission'-Spalte fehlt.

Problem: db.create_all() erstellt nur neue Tabellen, fuegt aber keine
Spalten zu bestehenden Tabellen hinzu. Wenn das Model neue Spalten
bekommt, crasht die App auf alten Datenbanken.

Loesung: _auto_migrate() vergleicht beim Start jede Model-Definition
mit dem tatsaechlichen DB-Schema (via SQLAlchemy Inspector) und fuegt
fehlende Spalten per ALTER TABLE ADD COLUMN hinzu. Funktioniert fuer
alle Datentypen mit korrekten Defaults (VARCHAR, INTEGER, BOOLEAN, etc.).

Output im Log: [Auto-Migrate] Added column share_links.permission (VARCHAR(20))

Das macht die App update-sicher - neue Spalten in Models werden
automatisch zur bestehenden DB hinzugefuegt, ohne manuelles Migrieren.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:01:34 +02:00
Stefan HackerandClaude Opus 4.6 1b716ae012 fix: DataTable Button-Clicks mit .stop + Share-Link Debug-Logging
- Alle Buttons in der Datei-Tabelle haben jetzt @click.stop
  (Download, Teilen, Umbenennen, Loeschen) damit die DataTable
  den Click nicht verschluckt
- Debug-Logging in createShare() um Frontend-Fehler sichtbar zu machen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 19:46:38 +02:00
Stefan HackerandClaude Opus 4.6 e1eb6a83ae feat: Share-Link Typ 'Nur Upload' (upload_only)
Dritter Link-Typ neben read und write:
- upload_only: Nur Dateien hochladen, kein Download, kein Ordnerinhalt
  sichtbar, Ordnername wird nicht angezeigt

Backend-Absicherung:
- GET /share/<token>/download gibt 403 bei upload_only
- POST /share/<token>/upload erlaubt upload_only + write
- GET /share/<token>/info gibt download_allowed zurueck

Frontend Share-Dialog:
- Drei Optionen: Nur Lesen / Lesen+Hochladen / Nur Upload
- Bestehende Links zeigen Typ an

Frontend ShareView:
- upload_only: Zeigt nur Upload-Zone, kein Dateiname, kein Download
- Hinweistext 'Dieser Link erlaubt nur das Hochladen von Dateien'

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:44:02 +02:00
Stefan HackerandClaude Opus 4.6 116c33a7dc feat: Share-Links mit Berechtigungen (Lesen / Lesen+Schreiben)
Share-Links haben jetzt ein permission-Feld (read/write):

- read (Standard): Nur Download erlaubt, kein Upload, kein Aendern
- write: Download + Upload in Ordner erlaubt

Backend-Absicherung:
- POST /share/<token>/upload prueft permission == 'write', gibt 403
  bei read-only Links zurueck
- GET /share/<token>/info gibt permission + upload_allowed zurueck
- ShareLink-Model hat neues permission-Feld (default: 'read')

Frontend Share-Dialog:
- Dropdown "Berechtigung" beim Erstellen von Links
  (Nur Lesen / Lesen+Hochladen)
- Bestehende Links zeigen Berechtigungslevel an

Frontend ShareView:
- Upload-Zone nur sichtbar wenn upload_allowed == true
- Bei read-only Links: kein Drag & Drop, kein Upload-Button

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:39:38 +02:00
Stefan HackerandClaude Opus 4.6 6a17748552 feat: Upload in freigegebene Ordner + Benachrichtigung
Share-Links fuer Ordner erlauben jetzt auch Uploads:

Backend:
- POST /share/<token>/upload - Datei in freigegebenen Ordner hochladen
- Passwort-Schutz wird bei Upload ebenfalls geprueft
- share_info gibt jetzt upload_allowed zurueck (true bei Ordner-Shares)
- Email-Benachrichtigung an den Ersteller wenn jemand eine Datei
  hochlaedt (Dateiname, Groesse, IP-Adresse)

Frontend (ShareView):
- Ordner-Shares zeigen jetzt eine Upload-Zone (Drag & Drop + Button)
- Fortschrittsbalken beim Upload mit Datei-Zaehler
- Erfolgs-/Fehlermeldung nach Upload
- Passwortgeschuetzte Ordner-Shares: erst entsperren, dann uploaden

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:35:10 +02:00
Stefan HackerandClaude Opus 4.6 e811210977 feat: System-Email-Benachrichtigungen bei Freigaben und Benutzer-Erstellung
Automatische E-Mail-Benachrichtigungen ueber die konfigurierte
System-Email bei folgenden Ereignissen:

- Datei/Ordner mit Benutzer geteilt -> Empfaenger wird benachrichtigt
- Share-Link heruntergeladen -> Ersteller wird benachrichtigt (mit IP)
- Kalender mit Benutzer geteilt -> Empfaenger wird benachrichtigt
- Adressbuch mit Benutzer geteilt -> Empfaenger wird benachrichtigt
- Passwort-Eintrag/-Ordner geteilt -> Empfaenger wird benachrichtigt
- Admin erstellt neuen Benutzer -> Neuer Benutzer wird benachrichtigt

Alle Benachrichtigungen sind fail-safe (try/except), damit die
eigentliche Aktion nie durch Email-Fehler blockiert wird.
Emails werden nur gesendet wenn System-SMTP konfiguriert ist UND
der Empfaenger eine Email-Adresse hat.

Neuer Service: app/services/system_mail.py mit zentralem Helper

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:31:19 +02:00
Stefan HackerandClaude Opus 4.6 61ce2ec244 feat: Drag & Drop Upload mit Ordner-Unterstuetzung
Dateien und komplette Verzeichnisse koennen jetzt hochgeladen werden:

Drag & Drop:
- Dateien per Drag & Drop auf den Datei-Explorer ziehen
- Ganze Ordner (inkl. Unterordner) per Drag & Drop hochladen
- Visuelles Overlay zeigt Drop-Zone an
- Ordnerstruktur wird automatisch auf dem Server nachgebildet

Buttons:
- "Dateien" Button: Mehrere Dateien auswaehlen (wie vorher)
- "Ordner" Button: Kompletten Ordner mit Unterordnern hochladen
  (nutzt webkitdirectory API)

Upload-Fortschritt:
- Fortschrittsbalken mit Datei-Zaehler waehrend des Uploads
- Fehlerhafte Uploads werden gezaehlt und gemeldet

Backend: /files/ensure-path Endpunkt erstellt verschachtelte
Ordnerstrukturen (z.B. "Docs/Work/Project") in einem Aufruf

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:17:39 +02:00
Stefan HackerandClaude Opus 4.6 10fde2396d feat: Einzeldatei-Restore aus Backups (lokal + SFTP)
Backup-Dateien koennen jetzt durchsucht werden ohne einen
Komplett-Restore durchfuehren zu muessen:

- "Einzelne Dateien durchsuchen" Button bei lokalen ZIP-Backups
- "Durchsuchen" Button bei jeder SFTP-Backup-Version
- Datei-Browser-Dialog mit:
  - Filterfeld zum Suchen nach Dateinamen
  - Dateianzahl-Anzeige (gefiltert/gesamt)
  - Icons nach Typ (DB, Metadaten, User-Dateien)
  - Download-Button: Einzelne Datei herunterladen
  - Restore-Button: Einzelne Datei direkt ins Live-System
    wiederherstellen (nur fuer files/-Eintraege)
- Browse-Session wird serverseitig verwaltet und beim Schliessen
  des Dialogs automatisch aufgeraeumt

Backend: /admin/restore/browse, /browse/<id>/download/<path>,
         /browse/<id>/restore-file, /browse/<id>/close
         + SFTP: /targets/<id>/versions/<name>/browse

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:13:16 +02:00
Stefan HackerandClaude Opus 4.6 d42d6d5d96 feat: SFTP-Backup mit Scheduler, Versionierung und Multi-Target
Mehrere SFTP-Backup-Ziele konfigurierbar mit:
- Host, Port, Benutzername, Passwort, Remote-Pfad
- Konfigurierbares Intervall (15 Min. bis woechentlich oder deaktiviert)
- Maximale Anzahl aufbewahrter Versionen (aeltere werden automatisch geloescht)
- Aktiv/Inaktiv-Toggle pro Ziel

Features:
- Automatischer Hintergrund-Scheduler prueft alle 60 Sekunden ob
  Backups faellig sind und fuehrt sie aus
- Manuelles Backup per Klick ("Jetzt sichern")
- SFTP-Verbindungstest-Button
- Versionen-Dialog: Alle Backup-Versionen auf dem SFTP-Server auflisten
  mit Groesse und Datum
- Restore direkt von SFTP: Version auswaehlen -> wird heruntergeladen
  und ueber die bestehende DB-Merge-Logik wiederhergestellt
- Chunked Upload zum SFTP in 16MB-Bloecken (fuer grosse Backups)
- Status-Anzeige: Letztes Backup, Erfolg/Fehler, Nachricht

Backend: BackupTarget Model, SFTP-Service (paramiko), Backup-Scheduler
API: /admin/backup/targets CRUD, /test, /run, /versions, /restore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:07:28 +02:00
Stefan HackerandClaude Opus 4.6 c6fe2c590f feat: Backup & Restore mit Chunked Upload fuer grosse Dateien
Backup:
- Erstellt streaming ZIP mit SQLite-DB (via sqlite3.backup API) +
  allen hochgeladenen Dateien + metadata.json
- Download als ZIP direkt aus dem Admin-Panel

Restore:
- Kleine Backups (<100MB): Direkter Upload
- Grosse Backups (>100MB bis TB+): Chunked Upload in 10MB-Stuecken
  mit Fortschrittsanzeige
- DB-Merge: INSERT OR REPLACE auf gemeinsame Spalten, so dass neue
  Schema-Aenderungen erhalten bleiben und Backup-Daten eingefuegt werden
- Dateien werden in data/files/ wiederhergestellt
- Restore-Anleitung direkt in der UI mit Hinweis auf SECRET_KEY/JWT_SECRET_KEY

Backend: /admin/backup, /admin/restore/init, /admin/restore/chunk,
         /admin/restore/finalize, /admin/restore/direct

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 17:55:39 +02:00
Stefan HackerandClaude Opus 4.6 0150bf4b2f feat: Passwort-Import aus Firefox, Chrome, Bitwarden und generischem CSV
- Firefox-Import: CSV aus Einstellungen > Passwoerter > Exportieren
  Domain wird automatisch als Titel extrahiert
- Generischer CSV-Import: Erkennt automatisch Spaltennamen aus
  Chrome, Bitwarden, 1Password und anderen Managern
- KeePass-Import bleibt bestehen
- Einheitlicher Import-Dialog mit Quellen-Auswahl (Dropdown)
- Jede Quelle zeigt eine kurze Anleitung an
- Alle Eintraege werden clientseitig verschluesselt vor dem Speichern
- Backend: /passwords/import/firefox und /passwords/import/csv Endpunkte

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 17:42:00 +02:00
Stefan HackerandClaude Opus 4.6 7220a2ef75 feat: Admin kann Email-Konten pro Benutzer verwalten + Benutzersuche
- Admin-Benutzer-Dialog hat jetzt zwei Tabs: Allgemein + E-Mail-Konten
- Im E-Mail-Konten-Tab: Konten fuer jeden Benutzer hinzufuegen,
  bearbeiten und loeschen (ohne sich als Benutzer einloggen zu muessen)
- Benutzersuche in der Benutzerverwaltung (filtert nach Name und Email)
- Backend: /admin/users/<id>/email-accounts GET/POST und
  /admin/email-accounts/<id> PUT/DELETE Endpunkte

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 17:35:51 +02:00
Stefan HackerandClaude Opus 4.6 113fe7140f feat: Registrierung default AN, Einladungslinks, System-Email
- Registrierung ist standardmaessig aktiviert (erster User = Admin)
- Einmal-Registrierungslinks: Admin kann Links generieren die auch bei
  deaktivierter Registrierung funktionieren, nach Nutzung ungueltig
- Optional Link per System-Email versenden
- System-SMTP in Admin-Einstellungen konfigurierbar:
  Server, Port, SSL, Benutzername, Passwort, Absender-Adresse
- SMTP-Verbindungstest-Button
- Register-Seite akzeptiert ?invite=TOKEN aus der URL

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 15:41:42 +02:00
Stefan HackerandClaude Opus 4.6 042a067e81 fix: Admin Edit-Button + Email-Kontenverwaltung in Einstellungen
- Fix: Admin Edit/Delete-Buttons reagieren jetzt (@click.stop)
- Neu: Email-Kontenverwaltung in den Benutzer-Einstellungen
  - IMAP/SMTP-Server, Port, SSL, Anmeldedaten konfigurieren
  - Konten hinzufuegen, bearbeiten, loeschen
  - Verbindungstest-Button
  - Standard-Konto festlegen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 15:30:29 +02:00
Stefan HackerandClaude Opus 4.6 35099de2c5 feat: Share-Dialog Fix, User-Sharing, Admin-Benutzerverwaltung, Registrierungs-Toggle
- Fix: Share-Dialog oeffnet sich jetzt auch bei bereits geteilten Dateien
- Neu: Dateien/Ordner direkt mit anderen Benutzern teilen (Lesen/Schreiben/Admin)
- Neu: Benutzersuche im Share-Dialog, bestehende Freigaben anzeigen/entfernen
- Neu: Admin kann Benutzer ueber die Weboberflaeche anlegen
- Neu: Admin kann Benutzer bearbeiten (Rolle, Quota, aktiv/inaktiv) und loeschen
- Neu: Schieberegler fuer oeffentliche Registrierung in den Admin-Einstellungen
- Neu: Register-Link auf Login-Seite nur sichtbar wenn Registrierung erlaubt
- Neu: Register-Seite leitet um wenn Registrierung deaktiviert
- Neu: AppSettings-Model fuer persistente App-Konfiguration
- Neu: /api/users/search Endpunkt fuer Benutzersuche in Share-Dialogen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 15:26:04 +02:00
Stefan HackerandClaude Opus 4.6 e7170b7cc8 docs: clarify port usage in README (dev vs production)
Port 3100 is the frontend dev server (open in browser), port 5000 is
the backend API only. In Docker production, everything runs on 5000.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 15:15:38 +02:00
Stefan HackerandClaude Opus 4.6 6e02e1a276 docs: add project README with installation and usage guide
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 15:10:42 +02:00
Stefan HackerandClaude Opus 4.6 99c2e3ed35 docs: add token generation command to .env.example
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 14:57:22 +02:00
Stefan HackerandClaude Opus 4.6 a8acd91955 chore: add frontend README from Vite template
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 14:54:11 +02:00
Stefan HackerandClaude Opus 4.6 62f550c373 feat: Mini-Cloud Plattform - komplette Implementierung Phase 0-8
Selbstgehostete Web-Cloud mit Dateiverwaltung, Kalender, Kontakte,
Email-Webclient, Office-Viewer und Passwort-Manager.

Backend (Flask/Python):
- JWT-Auth mit Access/Refresh Tokens, Benutzerverwaltung
- Dateien: Upload/Download, Ordner, Berechtigungen, Share-Links
- Kalender: CRUD, Teilen, iCal-Export, CalDAV well-known URLs
- Kontakte: Adressbuecher, vCard-Export, Teilen
- Email: IMAP/SMTP-Proxy, Multi-Account
- Office-Viewer: DOCX/XLSX/PPTX/PDF Vorschau
- Passwort-Manager: AES-256-GCM clientseitig, KeePass-Import
- Sync-API fuer Desktop/Mobile-Clients
- SQLite mit WAL-Modus

Frontend (Vue 3 + PrimeVue):
- Datei-Explorer mit Breadcrumbs und Share-Dialogen
- Monatskalender mit Event-Verwaltung
- Kontaktliste mit Adressbuch-Sidebar
- Email-Client mit 3-Spalten-Layout
- Passwort-Manager mit TOTP und Passwort-Generator
- Admin-Panel, Settings, oeffentliche Share-Seite

Docker: Multi-Stage Build, Bind Mounts (keine Volumes)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 14:53:28 +02:00
Stefan Hacker d4f7e90d0c first commit 2026-04-11 14:50:45 +02:00