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>
This commit is contained in:
Stefan Hacker
2026-04-11 18:44:02 +02:00
parent 116c33a7dc
commit e1eb6a83ae
3 changed files with 28 additions and 13 deletions
+10 -6
View File
@@ -421,8 +421,8 @@ def create_share_link(file_id):
max_downloads = data.get('max_downloads')
permission = data.get('permission', 'read')
if permission not in ('read', 'write'):
return jsonify({'error': 'Berechtigung muss "read" oder "write" sein'}), 400
if permission not in ('read', 'write', 'upload_only'):
return jsonify({'error': 'Berechtigung muss "read", "write" oder "upload_only" sein'}), 400
token = secrets.token_urlsafe(32)
password_hash = None
@@ -498,7 +498,8 @@ def share_info(token):
'mime_type': f.mime_type,
'has_password': bool(link.password_hash),
'permission': link.permission,
'upload_allowed': f.is_folder and link.permission == 'write',
'upload_allowed': f.is_folder and link.permission in ('write', 'upload_only'),
'download_allowed': link.permission in ('read', 'write'),
}), 200
@@ -531,6 +532,9 @@ def share_download(token):
if not link:
return jsonify({'error': 'Link nicht gefunden'}), 404
if link.permission == 'upload_only':
return jsonify({'error': 'Dieser Link erlaubt nur Upload, keinen Download'}), 403
if link.is_expired():
return jsonify({'error': 'Link abgelaufen'}), 410
@@ -576,9 +580,9 @@ def share_upload(token):
if link.is_expired():
return jsonify({'error': 'Link abgelaufen'}), 410
# Check write permission
if link.permission != 'write':
return jsonify({'error': 'Dieser Link erlaubt nur Lesen'}), 403
# Check write/upload permission
if link.permission not in ('write', 'upload_only'):
return jsonify({'error': 'Dieser Link erlaubt keinen Upload'}), 403
# Check password if set
if link.password_hash: