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>
This commit is contained in:
@@ -652,6 +652,40 @@ def share_download_file(token, file_id):
|
||||
download_name=target_file.name)
|
||||
|
||||
|
||||
@api_bp.route('/share/<token>/download-zip', methods=['GET'])
|
||||
def share_download_zip(token):
|
||||
"""Download the entire shared folder as ZIP."""
|
||||
link = ShareLink.query.filter_by(token=token).first()
|
||||
if not link:
|
||||
return jsonify({'error': 'Link nicht gefunden'}), 404
|
||||
|
||||
if link.is_expired():
|
||||
return jsonify({'error': 'Link abgelaufen'}), 410
|
||||
|
||||
if link.permission not in ('read', 'write'):
|
||||
return jsonify({'error': 'Download nicht erlaubt'}), 403
|
||||
|
||||
if link.password_hash:
|
||||
password = request.args.get('password', '') or request.headers.get('X-Share-Password', '')
|
||||
if not bcrypt.check_password_hash(link.password_hash, password):
|
||||
return jsonify({'error': 'Passwort erforderlich'}), 401
|
||||
|
||||
f = db.session.get(File, link.file_id)
|
||||
if not f.is_folder:
|
||||
return jsonify({'error': 'Kein Ordner'}), 400
|
||||
|
||||
link.download_count += 1
|
||||
db.session.commit()
|
||||
|
||||
try:
|
||||
from app.services.system_mail import notify_share_link_accessed
|
||||
notify_share_link_accessed(link, f.name, request.remote_addr)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return _download_folder_as_zip(f)
|
||||
|
||||
|
||||
@api_bp.route('/share/<token>/files/<int:file_id>', methods=['DELETE'])
|
||||
def share_delete_file(token, file_id):
|
||||
"""Delete a file from a shared folder (write permission required)."""
|
||||
|
||||
Reference in New Issue
Block a user