- Customer upload via token link (no login), optional password + expiry, drag & drop for files and folders with preserved structure - Admin portal with setup wizard, role-based users (admin/staff), per-customer WebDAV access rules (read/write), session auth - WebDAV container (Debian apache2) with htpasswd + access.conf auto-generated from the SQLite DB and reloaded via inotifywait - Configurable public base URL and janitor cron interval in admin UI; janitor reconciles the uploads table with the filesystem Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| public | ||
| src | ||
| webdav | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| Dockerfile | ||
| README.md | ||
| docker-compose.yml | ||
| package.json | ||
README.md
Simple File Upload
Kunden laden Dateien/Ordner über einen individuellen Link hoch (ohne Login). Admin + Sachbearbeiter verwalten Kunden im Adminportal und greifen per WebDAV zu.
Start
cp .env.example .env # optional: Ports anpassen
docker compose up -d --build
- Adminportal: http://localhost:3500/
- WebDAV:
webdav://HOST:1900/(Basic Auth, dieselben Benutzer wie im Adminportal)
Beim ersten Start öffnet sich ein Setup-Wizard — dort legst du den ersten Admin an.
Rollen
- Admin: legt Kunden + weitere Benutzer (Admins / Sachbearbeiter) an, verwaltet Upload-Links und pro-Kunde-Zugriffe. Hat WebDAV-Vollzugriff auf alles.
- Sachbearbeiter (Staff): sieht im Adminportal nur die Kunden, auf die ihm der Admin Zugriff erteilt hat. Per WebDAV greift er auf die zugeteilten Kundenordner zu (
readoderwrite). - Kunde: kein Login; Upload via individuellem Token-Link (optional mit Passwort + Ablaufdatum). Sieht keine Dateiliste.
Konfiguration
.env (Ports)
| Variable | Default | Zweck |
|---|---|---|
APP_PORT |
3500 |
Host-Port für Adminportal + Upload |
WEBDAV_PORT |
1900 |
Host-Port für WebDAV |
Admin-GUI → Einstellungen
- Öffentliche Basis-URL: wird in generierten Upload-Links verwendet. Leer = aus Request ableiten.
- Cron-Intervall (Minuten): periodischer DB/FS-Abgleich (entfernt verwaiste DB-Einträge von via WebDAV gelöschten Dateien und erfasst direkt per WebDAV hochgeladene Dateien).
Volumes
./data/db/→ SQLite-Datei neben derdocker-compose.yml./data/uploads/→ ein Unterordner pro Kunde (Slug)- Named Volume
webdav-config→ dynamisch generierte Apache-Config
Beide Container laufen als UID 1000:1000. Falls vorhandene Daten root gehören:
sudo chown -R 1000:1000 data/
Wie die WebDAV-ACLs funktionieren
Der App-Container erzeugt bei jeder Benutzer-/Kundenänderung:
/webdav-config/htpasswd— alle Benutzer (bcrypt-Hashes direkt aus DB)/webdav-config/access.conf— pro Kundenordner ein<Location>-Block:- gleiche Read- und Write-User → ein
Require user … - unterschiedliche →
<Limit GET PROPFIND OPTIONS HEAD>+<LimitExcept …>für saubere Trennung
- gleiche Read- und Write-User → ein
Der WebDAV-Container (Debian Apache) beobachtet das Verzeichnis via inotifywait und ruft apachectl graceful auf → Änderungen sind in ~2 Sek. wirksam.
Kunden-Upload
- Datei-Button, Ordner-Button oder Drag & Drop (Dateien und Ordner — Struktur bleibt erhalten).
- Optional Passwortabfrage, optional Ablaufdatum.
- Kunde sieht keine Dateiliste, nur eigenes Upload-Feedback.
WebDAV-Zugriff
- macOS Finder:
Gehe zu → Mit Server verbinden → http://HOST:1900/ - Windows: Netzlaufwerk hinzufügen →
http://HOST:1900/ - Linux / KDE Dolphin:
webdav://<user>@HOST:1900/ - Write-Rechte umfassen:
PUT,DELETE,MKCOL,MOVE,COPY,PROPPATCH,LOCK,UNLOCK. - In Dolphin löscht Shift+Entf direkt (umgeht den nicht existierenden WebDAV-Papierkorb).