mirror of
https://github.com/nextcloud/server.git
synced 2026-04-27 01:00:20 -04:00
fix: Access node owner by top level owner property
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
b99c088dc3
commit
57bd5d06c1
6 changed files with 136 additions and 20 deletions
|
|
@ -35,6 +35,7 @@
|
|||
:close-after-click="!isMenu(action.id)"
|
||||
:data-cy-files-list-row-action="action.id"
|
||||
:is-menu="isMenu(action.id)"
|
||||
:aria-label="action.title?.([source], currentView)"
|
||||
:title="action.title?.([source], currentView)"
|
||||
@click="onActionClick(action)">
|
||||
<template #icon>
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ export const entry = {
|
|||
source,
|
||||
id: fileid,
|
||||
mtime: new Date(),
|
||||
owner: getCurrentUser()?.uid || null,
|
||||
owner: context.owner,
|
||||
permissions: Permission.ALL,
|
||||
root: context?.root || '/files/' + getCurrentUser()?.uid,
|
||||
// Include mount-type from parent folder as this is inherited
|
||||
|
|
|
|||
|
|
@ -26,10 +26,9 @@ export const action = new FileAction({
|
|||
displayName(nodes: Node[]) {
|
||||
const node = nodes[0]
|
||||
const shareTypes = Object.values(node?.attributes?.['share-types'] || {}).flat() as number[]
|
||||
const ownerId = node?.attributes?.['owner-id']
|
||||
|
||||
if (shareTypes.length > 0
|
||||
|| (ownerId !== getCurrentUser()?.uid || isExternal(node))) {
|
||||
|| (node.owner !== getCurrentUser()?.uid || isExternal(node))) {
|
||||
return t('files_sharing', 'Shared')
|
||||
}
|
||||
|
||||
|
|
@ -38,19 +37,32 @@ export const action = new FileAction({
|
|||
|
||||
title(nodes: Node[]) {
|
||||
const node = nodes[0]
|
||||
const ownerId = node?.attributes?.['owner-id']
|
||||
const ownerDisplayName = node?.attributes?.['owner-display-name']
|
||||
|
||||
// Mixed share types
|
||||
if (Array.isArray(node.attributes?.['share-types']) && node.attributes?.['share-types'].length > 1) {
|
||||
return t('files_sharing', 'Shared multiple times with different people')
|
||||
}
|
||||
|
||||
if (ownerId && (ownerId !== getCurrentUser()?.uid || isExternal(node))) {
|
||||
if (node.owner && (node.owner !== getCurrentUser()?.uid || isExternal(node))) {
|
||||
const ownerDisplayName = node?.attributes?.['owner-display-name']
|
||||
return t('files_sharing', 'Shared by {ownerDisplayName}', { ownerDisplayName })
|
||||
}
|
||||
|
||||
return t('files_sharing', 'Show sharing options')
|
||||
const shareTypes = Object.values(node?.attributes?.['share-types'] || {}).flat() as number[]
|
||||
if (shareTypes.length > 1) {
|
||||
return t('files_sharing', 'Shared multiple times with different people')
|
||||
}
|
||||
|
||||
const sharees = node.attributes.sharees?.sharee as { id: string, 'display-name': string, type: ShareType }[] | undefined
|
||||
if (!sharees) {
|
||||
// No sharees so just show the default message to create a new share
|
||||
return t('files_sharing', 'Show sharing options')
|
||||
}
|
||||
|
||||
const sharee = [sharees].flat()[0] // the property is sometimes weirdly normalized, so we need to compensate
|
||||
switch (sharee.type) {
|
||||
case ShareType.User:
|
||||
return t('files_sharing', 'Shared with {user}', { user: sharee['display-name'] })
|
||||
case ShareType.Group:
|
||||
return t('files_sharing', 'Shared with group {group}', { group: sharee['display-name'] ?? sharee.id })
|
||||
default:
|
||||
return t('files_sharing', 'Shared with others')
|
||||
}
|
||||
},
|
||||
|
||||
iconSvgInline(nodes: Node[]) {
|
||||
|
|
@ -69,7 +81,7 @@ export const action = new FileAction({
|
|||
}
|
||||
|
||||
// Group shares
|
||||
if (shareTypes.includes(ShareType.Grup)
|
||||
if (shareTypes.includes(ShareType.Group)
|
||||
|| shareTypes.includes(ShareType.RemoteGroup)) {
|
||||
return AccountGroupSvg
|
||||
}
|
||||
|
|
@ -79,9 +91,8 @@ export const action = new FileAction({
|
|||
return CircleSvg
|
||||
}
|
||||
|
||||
const ownerId = node?.attributes?.['owner-id']
|
||||
if (ownerId && (ownerId !== getCurrentUser()?.uid || isExternal(node))) {
|
||||
return generateAvatarSvg(ownerId, isExternal(node))
|
||||
if (node.owner && (node.owner !== getCurrentUser()?.uid || isExternal(node))) {
|
||||
return generateAvatarSvg(node.owner, isExternal(node))
|
||||
}
|
||||
|
||||
return AccountPlusSvg
|
||||
|
|
@ -93,7 +104,6 @@ export const action = new FileAction({
|
|||
}
|
||||
|
||||
const node = nodes[0]
|
||||
const ownerId = node?.attributes?.['owner-id']
|
||||
const shareTypes = node.attributes?.['share-types']
|
||||
const isMixed = Array.isArray(shareTypes) && shareTypes.length > 0
|
||||
|
||||
|
|
@ -104,7 +114,7 @@ export const action = new FileAction({
|
|||
}
|
||||
|
||||
// If the node is shared by someone else
|
||||
if (ownerId && (ownerId !== getCurrentUser()?.uid || isExternal(node))) {
|
||||
if (node.owner !== getCurrentUser()?.uid || isExternal(node)) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ async function updateAvailableAccounts(path: string = '/') {
|
|||
const { contents } = await currentView.value.getContents(path)
|
||||
const available = new Map<string, IUserSelectData>()
|
||||
for (const node of contents) {
|
||||
const owner = node.owner ?? node.attributes['owner-id']
|
||||
const owner = node.owner
|
||||
if (owner && !available.has(owner)) {
|
||||
available.set(owner, {
|
||||
id: owner,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import NcUserBubble from '@nextcloud/vue/dist/Components/NcUserBubble.js'
|
|||
const folder = ref<Folder>()
|
||||
const note = computed<string>(() => folder.value?.attributes.note ?? '')
|
||||
const user = computed(() => {
|
||||
const id = folder.value?.attributes?.['owner-id']
|
||||
const id = folder.value?.owner
|
||||
const displayName = folder.value?.attributes?.['owner-display-name']
|
||||
if (id !== getCurrentUser()?.uid) {
|
||||
return {
|
||||
|
|
|
|||
105
cypress/e2e/files_sharing/files-inline-action.cy.ts
Normal file
105
cypress/e2e/files_sharing/files-inline-action.cy.ts
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*!
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import type { User } from '@nextcloud/cypress'
|
||||
import { createShare } from './FilesSharingUtils.ts'
|
||||
import { closeSidebar, getRowForFile } from '../files/FilesUtils.ts'
|
||||
|
||||
describe('files_sharing: Files inline status action', { testIsolation: true }, () => {
|
||||
/**
|
||||
* Regression test of https://github.com/nextcloud/server/issues/45723
|
||||
*/
|
||||
it('No "shared" tag when user ID is purely numerical', () => {
|
||||
const user = {
|
||||
language: 'en',
|
||||
password: 'test1234',
|
||||
userId: String(Math.floor(Math.random() * 1000)),
|
||||
} as User
|
||||
cy.createUser(user)
|
||||
cy.mkdir(user, '/folder')
|
||||
cy.login(user)
|
||||
|
||||
cy.visit('/apps/files')
|
||||
|
||||
getRowForFile('folder')
|
||||
.should('be.visible')
|
||||
.find('[data-cy-files-list-row-actions]')
|
||||
.findByRole('button', { name: 'Shared' })
|
||||
.should('not.exist')
|
||||
})
|
||||
|
||||
describe('', () => {
|
||||
let user: User
|
||||
let sharee: User
|
||||
|
||||
beforeEach(() => {
|
||||
cy.createRandomUser().then(($user) => {
|
||||
user = $user
|
||||
})
|
||||
cy.createRandomUser().then(($user) => {
|
||||
sharee = $user
|
||||
})
|
||||
})
|
||||
|
||||
it('Render quick option for sharing', () => {
|
||||
cy.mkdir(user, '/folder')
|
||||
cy.login(user)
|
||||
|
||||
cy.visit('/apps/files')
|
||||
getRowForFile('folder')
|
||||
.should('be.visible')
|
||||
|
||||
getRowForFile('folder')
|
||||
.should('be.visible')
|
||||
.find('[data-cy-files-list-row-actions]')
|
||||
.findByRole('button', { name: /Show sharing options/ })
|
||||
.should('be.visible')
|
||||
.click()
|
||||
|
||||
// check the click opened the sidebar
|
||||
cy.get('[data-cy-sidebar]')
|
||||
.should('be.visible')
|
||||
// and ensure the sharing tab is selected
|
||||
.findByRole('tab', { name: 'Sharing', selected: true })
|
||||
.should('exist')
|
||||
})
|
||||
|
||||
it('Render inline status action for sharer', () => {
|
||||
cy.mkdir(user, '/folder')
|
||||
cy.login(user)
|
||||
|
||||
cy.visit('/apps/files')
|
||||
getRowForFile('folder')
|
||||
.should('be.visible')
|
||||
createShare('folder', sharee.userId)
|
||||
closeSidebar()
|
||||
|
||||
getRowForFile('folder')
|
||||
.should('be.visible')
|
||||
.find('[data-cy-files-list-row-actions]')
|
||||
.findByRole('button', { name: /^Shared with/i })
|
||||
.should('be.visible')
|
||||
})
|
||||
|
||||
it('Render inline status action for sharee', () => {
|
||||
cy.mkdir(user, '/folder')
|
||||
cy.login(user)
|
||||
|
||||
cy.visit('/apps/files')
|
||||
getRowForFile('folder')
|
||||
.should('be.visible')
|
||||
createShare('folder', sharee.userId)
|
||||
closeSidebar()
|
||||
|
||||
cy.login(sharee)
|
||||
cy.visit('/apps/files')
|
||||
|
||||
getRowForFile('folder')
|
||||
.should('be.visible')
|
||||
.find('[data-cy-files-list-row-actions]')
|
||||
.findByRole('button', { name: `Shared by ${user.userId}` })
|
||||
.should('be.visible')
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Reference in a new issue