mirror of
https://github.com/nextcloud/server.git
synced 2026-02-20 00:12:30 -05:00
fix(files_versions): correctly show version author also for shared files
The users endpoint is not available for other users if the current user has no admin privileges, so instead use the displaynames endpoint. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
efa5632bba
commit
00a1f23913
4 changed files with 111 additions and 42 deletions
|
|
@ -31,16 +31,19 @@
|
|||
<div class="version__info">
|
||||
<div v-if="versionLabel"
|
||||
class="version__info__label"
|
||||
data-cy-files-version-label
|
||||
:title="versionLabel">
|
||||
{{ versionLabel }}
|
||||
</div>
|
||||
<div v-if="versionAuthor" class="version__info">
|
||||
<div v-if="versionAuthor"
|
||||
class="version__info"
|
||||
data-cy-files-version-author-name>
|
||||
<span v-if="versionLabel">•</span>
|
||||
<NcAvatar class="avatar"
|
||||
:user="version.author"
|
||||
:size="16"
|
||||
:disable-menu="true"
|
||||
:disable-tooltip="true"
|
||||
:size="20"
|
||||
disable-menu
|
||||
disable-tooltip
|
||||
:show-user-status="false" />
|
||||
<div>{{ versionAuthor }}</div>
|
||||
</div>
|
||||
|
|
@ -53,7 +56,7 @@
|
|||
<NcDateTime class="version__info__date"
|
||||
relative-time="short"
|
||||
:timestamp="version.mtime" />
|
||||
<!-- Separate dot to improve alignement -->
|
||||
<!-- Separate dot to improve alignment -->
|
||||
<span>•</span>
|
||||
<span>{{ humanReadableSize }}</span>
|
||||
</div>
|
||||
|
|
@ -114,8 +117,18 @@
|
|||
import type { PropType } from 'vue'
|
||||
import type { Version } from '../utils/versions'
|
||||
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { Permission, formatFileSize } from '@nextcloud/files'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { joinPaths } from '@nextcloud/paths'
|
||||
import { getRootUrl, generateUrl } from '@nextcloud/router'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
import axios from '@nextcloud/axios'
|
||||
import moment from '@nextcloud/moment'
|
||||
import logger from '../utils/logger'
|
||||
|
||||
import BackupRestore from 'vue-material-design-icons/BackupRestore.vue'
|
||||
import Delete from 'vue-material-design-icons/Delete.vue'
|
||||
import Download from 'vue-material-design-icons/Download.vue'
|
||||
|
|
@ -130,14 +143,6 @@ import NcDateTime from '@nextcloud/vue/components/NcDateTime'
|
|||
import NcListItem from '@nextcloud/vue/components/NcListItem'
|
||||
import Tooltip from '@nextcloud/vue/directives/Tooltip'
|
||||
|
||||
import { Permission, formatFileSize } from '@nextcloud/files'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { joinPaths } from '@nextcloud/paths'
|
||||
import { getRootUrl, generateOcsUrl } from '@nextcloud/router'
|
||||
import axios from '@nextcloud/axios'
|
||||
import moment from '@nextcloud/moment'
|
||||
|
||||
const hasPermission = (permissions: number, permission: number): boolean => (permissions & permission) !== 0
|
||||
|
||||
export default defineComponent({
|
||||
|
|
@ -295,21 +300,26 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
async fetchDisplayName() {
|
||||
// check to make sure that we have a valid author - in case database did not migrate, null author, etc.
|
||||
if (this.version.author) {
|
||||
this.versionAuthor = null
|
||||
if (!this.version.author) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.version.author === getCurrentUser()?.uid) {
|
||||
this.versionAuthor = t('files_versions', 'You')
|
||||
} else {
|
||||
try {
|
||||
const { data } = await axios.get(generateOcsUrl(`/cloud/users/${this.version.author}`))
|
||||
this.versionAuthor = data.ocs.data.displayname
|
||||
} catch (e) {
|
||||
// Promise got rejected - default to null author to not try to load author profile
|
||||
this.versionAuthor = null
|
||||
const { data } = await axios.post(generateUrl('/displaynames'), { users: [this.version.author] })
|
||||
this.versionAuthor = data.users[this.version.author]
|
||||
} catch (error) {
|
||||
logger.warn('Could not load user display name', { error })
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
click() {
|
||||
if (!this.canView) {
|
||||
window.location = this.downloadURL
|
||||
window.location.href = this.downloadURL
|
||||
return
|
||||
}
|
||||
this.$emit('click', { version: this.version })
|
||||
|
|
|
|||
|
|
@ -4,28 +4,27 @@
|
|||
-->
|
||||
<template>
|
||||
<div class="versions-tab__container">
|
||||
<VirtualScrolling :sections="sections"
|
||||
<VirtualScrolling v-slot="{ visibleSections }"
|
||||
:sections="sections"
|
||||
:header-height="0">
|
||||
<template slot-scope="{visibleSections}">
|
||||
<ul data-files-versions-versions-list>
|
||||
<template v-if="visibleSections.length === 1">
|
||||
<Version v-for="(row) of visibleSections[0].rows"
|
||||
:key="row.items[0].mtime"
|
||||
:can-view="canView"
|
||||
:can-compare="canCompare"
|
||||
:load-preview="isActive"
|
||||
:version="row.items[0]"
|
||||
:file-info="fileInfo"
|
||||
:is-current="row.items[0].mtime === fileInfo.mtime"
|
||||
:is-first-version="row.items[0].mtime === initialVersionMtime"
|
||||
@click="openVersion"
|
||||
@compare="compareVersion"
|
||||
@restore="handleRestore"
|
||||
@label-update-request="handleLabelUpdateRequest(row.items[0])"
|
||||
@delete="handleDelete" />
|
||||
</template>
|
||||
</ul>
|
||||
</template>
|
||||
<ul :aria-label="t('files_versions', 'File versions')" data-files-versions-versions-list>
|
||||
<template v-if="visibleSections.length === 1">
|
||||
<Version v-for="(row) of visibleSections[0].rows"
|
||||
:key="row.items[0].mtime"
|
||||
:can-view="canView"
|
||||
:can-compare="canCompare"
|
||||
:load-preview="isActive"
|
||||
:version="row.items[0]"
|
||||
:file-info="fileInfo"
|
||||
:is-current="row.items[0].mtime === fileInfo.mtime"
|
||||
:is-first-version="row.items[0].mtime === initialVersionMtime"
|
||||
@click="openVersion"
|
||||
@compare="compareVersion"
|
||||
@restore="handleRestore"
|
||||
@label-update-request="handleLabelUpdateRequest(row.items[0])"
|
||||
@delete="handleDelete" />
|
||||
</template>
|
||||
</ul>
|
||||
<NcLoadingIcon v-if="loading" slot="loader" class="files-list-viewer__loader" />
|
||||
</VirtualScrolling>
|
||||
<VersionLabelDialog v-if="editedVersion"
|
||||
|
|
|
|||
|
|
@ -30,4 +30,18 @@ describe('Versions creation', () => {
|
|||
cy.get('[data-files-versions-version]').eq(2).contains('Initial version')
|
||||
})
|
||||
})
|
||||
|
||||
it('See yourself as version author', () => {
|
||||
cy.visit('/apps/files')
|
||||
openVersionsPanel(randomFileName)
|
||||
|
||||
cy.findByRole('tabpanel', { name: 'Versions' })
|
||||
.findByRole('list', { name: 'File versions' })
|
||||
.findAllByRole('listitem')
|
||||
.should('have.length', 3)
|
||||
.first()
|
||||
.find('[data-cy-files-version-author-name]')
|
||||
.should('exist')
|
||||
.and('contain.text', 'You')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
46
cypress/e2e/files_versions/version_sharing.cy.ts
Normal file
46
cypress/e2e/files_versions/version_sharing.cy.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import type { User } from '@nextcloud/cypress'
|
||||
import { openVersionsPanel, setupTestSharedFileFromUser, uploadThreeVersions } from './filesVersionsUtils.ts'
|
||||
import { navigateToFolder, triggerActionForFile } from '../files/FilesUtils.ts'
|
||||
|
||||
describe('Versions on shares', () => {
|
||||
const randomSharedFolderName = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 10)
|
||||
const randomFileName = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 10) + '.txt'
|
||||
const randomFilePath = `${randomSharedFolderName}/${randomFileName}`
|
||||
let alice: User
|
||||
let bob: User
|
||||
|
||||
before(() => {
|
||||
cy.createRandomUser()
|
||||
.then((user) => {
|
||||
alice = user
|
||||
})
|
||||
.then(() => {
|
||||
cy.mkdir(alice, `/${randomSharedFolderName}`)
|
||||
return setupTestSharedFileFromUser(alice, randomSharedFolderName, {})
|
||||
})
|
||||
.then((user) => { bob = user })
|
||||
.then(() => uploadThreeVersions(alice, randomFilePath))
|
||||
})
|
||||
|
||||
it('See sharees display name as author', () => {
|
||||
cy.login(bob)
|
||||
cy.visit('/apps/files')
|
||||
|
||||
navigateToFolder(randomSharedFolderName)
|
||||
|
||||
triggerActionForFile(randomFileName, 'details')
|
||||
cy.findByRole('tab', { name: 'Versions' }).click()
|
||||
|
||||
cy.findByRole('tabpanel', { name: 'Versions' })
|
||||
.findByRole('list', { name: 'File versions' })
|
||||
.findAllByRole('listitem')
|
||||
.first()
|
||||
.find('[data-cy-files-version-author-name]')
|
||||
.should('be.visible')
|
||||
.and('contain.text', alice.userId)
|
||||
})
|
||||
})
|
||||
Loading…
Reference in a new issue