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>
This commit is contained in:
@@ -162,6 +162,10 @@
|
||||
<div class="share-section">
|
||||
<h5>Freigabe-Link erstellen</h5>
|
||||
<div class="share-form">
|
||||
<div class="field">
|
||||
<label>Berechtigung</label>
|
||||
<Select v-model="shareLinkPermission" :options="linkPermOptions" optionLabel="label" optionValue="value" fluid />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Passwort (optional)</label>
|
||||
<Password v-model="sharePassword" :feedback="false" toggle-mask fluid />
|
||||
@@ -180,7 +184,8 @@
|
||||
<div class="link-info">
|
||||
<code>{{ currentOrigin }}/share/{{ link.token }}</code>
|
||||
<small>
|
||||
{{ link.download_count }} Downloads
|
||||
{{ link.permission === 'write' ? 'Lesen+Schreiben' : 'Nur Lesen' }}
|
||||
| {{ link.download_count }} Downloads
|
||||
<template v-if="link.expires_at"> | Bis {{ formatDate(link.expires_at) }}</template>
|
||||
<template v-if="link.has_password"> | Passwortgeschuetzt</template>
|
||||
</small>
|
||||
@@ -250,6 +255,8 @@ const selectedShareUser = ref(null)
|
||||
const shareUserPermission = ref('read')
|
||||
const userSearchResults = ref([])
|
||||
const userPermOptions = [{ label: 'Lesen', value: 'read' }, { label: 'Schreiben', value: 'write' }, { label: 'Admin', value: 'admin' }]
|
||||
const linkPermOptions = [{ label: 'Nur Lesen (Download)', value: 'read' }, { label: 'Lesen + Hochladen (nur Ordner)', value: 'write' }]
|
||||
const shareLinkPermission = ref('read')
|
||||
const currentOrigin = window.location.origin
|
||||
const shareLoading = ref(false)
|
||||
const showDeleteConfirm = ref(false)
|
||||
@@ -580,13 +587,14 @@ async function createShare() {
|
||||
if (!shareFile.value) return
|
||||
shareLoading.value = true
|
||||
try {
|
||||
const opts = {}
|
||||
const opts = { permission: shareLinkPermission.value }
|
||||
if (sharePassword.value) opts.password = sharePassword.value
|
||||
if (shareExpiry.value) opts.expires_at = shareExpiry.value
|
||||
await filesStore.createShareLink(shareFile.value.id, opts)
|
||||
shareLinks.value = await filesStore.getShareLinks(shareFile.value.id)
|
||||
sharePassword.value = ''
|
||||
shareExpiry.value = ''
|
||||
shareLinkPermission.value = 'read'
|
||||
toast.add({ severity: 'success', summary: 'Link erstellt', life: 3000 })
|
||||
} catch (err) {
|
||||
toast.add({ severity: 'error', summary: 'Fehler', detail: err.response?.data?.error, life: 5000 })
|
||||
|
||||
Reference in New Issue
Block a user