mirror of
https://github.com/nextcloud/server.git
synced 2026-04-22 14:50:17 -04:00
fix(files): Do not add click listener if there is no default action on public shares
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
cb4c569486
commit
018af2a2fe
3 changed files with 46 additions and 31 deletions
|
|
@ -2,13 +2,12 @@
|
|||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import type { ShareAttribute } from '../../../files_sharing/src/sharing'
|
||||
|
||||
import { FileAction, Permission, Node, FileType, View, DefaultType } from '@nextcloud/files'
|
||||
import { FileAction, Node, FileType, View, DefaultType } from '@nextcloud/files'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { getSharingToken, isPublicShare } from '@nextcloud/sharing/public'
|
||||
import { basename } from 'path'
|
||||
import { isDownloadable } from '../utils/permissions'
|
||||
|
||||
import ArrowDownSvg from '@mdi/svg/svg/arrow-down.svg?raw'
|
||||
|
||||
|
|
@ -40,23 +39,6 @@ const downloadNodes = function(dir: string, nodes: Node[]) {
|
|||
triggerDownload(url)
|
||||
}
|
||||
|
||||
const isDownloadable = function(node: Node) {
|
||||
if ((node.permissions & Permission.READ) === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
// If the mount type is a share, ensure it got download permissions.
|
||||
if (node.attributes['share-attributes']) {
|
||||
const shareAttributes = JSON.parse(node.attributes['share-attributes'] || '[]') as Array<ShareAttribute>
|
||||
const downloadAttribute = shareAttributes.find(({ scope, key }: ShareAttribute) => scope === 'permissions' && key === 'download')
|
||||
if (downloadAttribute) {
|
||||
return downloadAttribute.value === true
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export const action = new FileAction({
|
||||
id: 'download',
|
||||
default: DefaultType.DEFAULT,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import { getDragAndDropPreview } from '../utils/dragUtils.ts'
|
|||
import { hashCode } from '../utils/hashUtils.ts'
|
||||
import { dataTransferToFileTree, onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts'
|
||||
import logger from '../logger.ts'
|
||||
import { isDownloadable } from '../utils/permissions.ts'
|
||||
|
||||
Vue.directive('onClickOutside', vOnClickOutside)
|
||||
|
||||
|
|
@ -270,29 +271,31 @@ export default defineComponent({
|
|||
event.stopPropagation()
|
||||
},
|
||||
|
||||
execDefaultAction(event) {
|
||||
execDefaultAction(event: MouseEvent) {
|
||||
// Ignore click if we are renaming
|
||||
if (this.isRenaming) {
|
||||
return
|
||||
}
|
||||
|
||||
// Ignore right click.
|
||||
if (event.button > 1) {
|
||||
// Ignore right click (button & 2) and any auxillary button expect mouse-wheel (button & 4)
|
||||
if (Boolean(event.button & 2) || event.button > 4) {
|
||||
return
|
||||
}
|
||||
|
||||
// if ctrl+click or middle mouse button, open in new tab
|
||||
// if ctrl+click / cmd+click (MacOS uses the meta key) or middle mouse button (button & 4), open in new tab
|
||||
// also if there is no default action use this as a fallback
|
||||
const metaKeyPressed = event.ctrlKey || event.metaKey || event.button === 1
|
||||
const metaKeyPressed = event.ctrlKey || event.metaKey || Boolean(event.button & 4)
|
||||
if (metaKeyPressed || !this.defaultFileAction) {
|
||||
// If no download permission, then we can not allow to download (direct link) the files
|
||||
if (isPublicShare() && !isDownloadable(this.source)) {
|
||||
return
|
||||
}
|
||||
|
||||
const url = isPublicShare()
|
||||
? this.source.encodedSource
|
||||
: generateUrl('/f/{fileId}', { fileId: this.fileid })
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
let url: string
|
||||
if (isPublicShare()) {
|
||||
url = this.source.encodedSource
|
||||
} else {
|
||||
url = generateUrl('/f/{fileId}', { fileId: this.fileid })
|
||||
}
|
||||
window.open(url, metaKeyPressed ? '_self' : undefined)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
30
apps/files/src/utils/permissions.ts
Normal file
30
apps/files/src/utils/permissions.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*!
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import type { Node } from '@nextcloud/files'
|
||||
import type { ShareAttribute } from '../../../files_sharing/src/sharing.ts'
|
||||
|
||||
import { Permission } from '@nextcloud/files'
|
||||
|
||||
/**
|
||||
* Check permissions on the node if it can be downloaded
|
||||
* @param node The node to check
|
||||
* @return True if downloadable, false otherwise
|
||||
*/
|
||||
export function isDownloadable(node: Node): boolean {
|
||||
if ((node.permissions & Permission.READ) === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
// If the mount type is a share, ensure it got download permissions.
|
||||
if (node.attributes['share-attributes']) {
|
||||
const shareAttributes = JSON.parse(node.attributes['share-attributes'] || '[]') as Array<ShareAttribute>
|
||||
const downloadAttribute = shareAttributes.find(({ scope, key }: ShareAttribute) => scope === 'permissions' && key === 'download')
|
||||
if (downloadAttribute !== undefined) {
|
||||
return downloadAttribute.value === true
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
Loading…
Reference in a new issue