aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorStephan Orbaugh <62374139+sorbaugh@users.noreply.github.com>2024-09-10 17:17:03 +0200
committerGitHub <noreply@github.com>2024-09-10 17:17:03 +0200
commit2a1df3b7fcf5d4892728fe27b3c7a59f807dc369 (patch)
tree84e8d8e555e65c5008903ba9adaba3c129325ec9 /apps
parent3c2ead71330b2510b2266c9883d1d0b157424425 (diff)
parent8a77d84d379586ecba40a4892a060b50bb0f884b (diff)
downloadnextcloud-server-2a1df3b7fcf5d4892728fe27b3c7a59f807dc369.tar.gz
nextcloud-server-2a1df3b7fcf5d4892728fe27b3c7a59f807dc369.zip
Merge pull request #47797 from nextcloud/backport/47692/stable28
[stable28] fix(files): Correctly parse external shares for files UI
Diffstat (limited to 'apps')
-rw-r--r--apps/files_sharing/src/services/SharingService.spec.ts48
-rw-r--r--apps/files_sharing/src/services/SharingService.ts25
2 files changed, 65 insertions, 8 deletions
diff --git a/apps/files_sharing/src/services/SharingService.spec.ts b/apps/files_sharing/src/services/SharingService.spec.ts
index ed3a0cb6590..ef9690d094e 100644
--- a/apps/files_sharing/src/services/SharingService.spec.ts
+++ b/apps/files_sharing/src/services/SharingService.spec.ts
@@ -287,6 +287,25 @@ describe('SharingService share to Node mapping', () => {
tags: [window.OC.TAG_FAVORITE],
}
+ const remoteFile = {
+ mimetype: 'text/markdown',
+ mtime: 1688721600,
+ permissions: 19,
+ type: 'file',
+ file_id: 1234,
+ id: 4,
+ share_type: Type.SHARE_TYPE_USER,
+ parent: null,
+ remote: 'http://exampe.com',
+ remote_id: '12345',
+ share_token: 'share-token',
+ name: '/test.md',
+ mountpoint: '/shares/test.md',
+ owner: 'owner-uid',
+ user: 'sharee-uid',
+ accepted: true,
+ }
+
test('File', async () => {
jest.spyOn(axios, 'get').mockReturnValueOnce(Promise.resolve({
data: {
@@ -346,6 +365,35 @@ describe('SharingService share to Node mapping', () => {
expect(folder.attributes.favorite).toBe(1)
})
+ test('Remote file', async () => {
+ jest.spyOn(axios, 'get').mockReturnValueOnce(Promise.resolve({
+ data: {
+ ocs: {
+ data: [remoteFile],
+ },
+ },
+ }))
+
+ const shares = await getContents(false, true, false, false)
+
+ expect(axios.get).toHaveBeenCalledTimes(1)
+ expect(shares.contents).toHaveLength(1)
+
+ const file = shares.contents[0] as File
+ expect(file).toBeInstanceOf(File)
+ expect(file.fileid).toBe(1234)
+ expect(file.source).toBe('http://localhost/remote.php/dav/files/test/shares/test.md')
+ expect(file.owner).toBe('owner-uid')
+ expect(file.mime).toBe('text/markdown')
+ expect(file.mtime?.getTime()).toBe(remoteFile.mtime * 1000)
+ // not available for remote shares
+ expect(file.size).toBe(undefined)
+ expect(file.permissions).toBe(0)
+ expect(file.root).toBe('/files/test')
+ expect(file.attributes).toBeInstanceOf(Object)
+ expect(file.attributes.favorite).toBe(0)
+ })
+
test('Empty', async () => {
jest.spyOn(logger, 'error').mockImplementationOnce(() => {})
jest.spyOn(axios, 'get').mockReturnValueOnce(Promise.resolve({
diff --git a/apps/files_sharing/src/services/SharingService.ts b/apps/files_sharing/src/services/SharingService.ts
index a4c63bec7b0..11989bdb8a9 100644
--- a/apps/files_sharing/src/services/SharingService.ts
+++ b/apps/files_sharing/src/services/SharingService.ts
@@ -50,10 +50,16 @@ const ocsEntryToNode = async function(ocsEntry: any): Promise<Folder | File | nu
try {
// Federated share handling
if (ocsEntry?.remote_id !== undefined) {
- const mime = (await import('mime')).default
- // This won't catch files without an extension, but this is the best we can do
- ocsEntry.mimetype = mime.getType(ocsEntry.name)
- ocsEntry.item_type = ocsEntry.mimetype ? 'file' : 'folder'
+ if (!ocsEntry.mimetype) {
+ const mime = (await import('mime')).default
+ // This won't catch files without an extension, but this is the best we can do
+ ocsEntry.mimetype = mime.getType(ocsEntry.name)
+ }
+ ocsEntry.item_type = ocsEntry.type || (ocsEntry.mimetype ? 'file' : 'folder')
+
+ // different naming for remote shares
+ ocsEntry.item_mtime = ocsEntry.mtime
+ ocsEntry.file_target = ocsEntry.file_target || ocsEntry.mountpoint
// Need to set permissions to NONE for federated shares
ocsEntry.item_permissions = Permission.NONE
@@ -70,14 +76,15 @@ const ocsEntryToNode = async function(ocsEntry: any): Promise<Folder | File | nu
// If this is an external share that is not yet accepted,
// we don't have an id. We can fallback to the row id temporarily
- const fileid = ocsEntry.file_source || ocsEntry.id
+ // local shares (this server) use `file_source`, but remote shares (federated) use `file_id`
+ const fileid = ocsEntry.file_source || ocsEntry.file_id || ocsEntry.id
// Generate path and strip double slashes
- const path = ocsEntry?.path || ocsEntry.file_target || ocsEntry.name
+ const path = ocsEntry.path || ocsEntry.file_target || ocsEntry.name
const source = generateRemoteUrl(`dav/${rootPath}/${path}`.replaceAll(/\/\//gm, '/'))
+ let mtime = ocsEntry.item_mtime ? new Date((ocsEntry.item_mtime) * 1000) : undefined
// Prefer share time if more recent than item mtime
- let mtime = ocsEntry?.item_mtime ? new Date((ocsEntry.item_mtime) * 1000) : undefined
if (ocsEntry?.stime > (ocsEntry?.item_mtime || 0)) {
mtime = new Date((ocsEntry.stime) * 1000)
}
@@ -169,6 +176,8 @@ const getDeletedShares = function(): AxiosPromise<OCSResponse<any>> {
/**
* Group an array of objects (here Nodes) by a key
* and return an array of arrays of them.
+ * @param nodes Nodes to group
+ * @param key The attribute to group by
*/
const groupBy = function(nodes: (Folder | File)[], key: string) {
return Object.values(nodes.reduce(function(acc, curr) {
@@ -178,7 +187,7 @@ const groupBy = function(nodes: (Folder | File)[], key: string) {
}
export const getContents = async (sharedWithYou = true, sharedWithOthers = true, pendingShares = false, deletedshares = false, filterTypes: number[] = []): Promise<ContentsWithRoot> => {
- const promises = [] as AxiosPromise<OCSResponse<any>>[]
+ const promises = [] as AxiosPromise<OCSResponse<unknown>>[]
if (sharedWithYou) {
promises.push(getSharedWithYou(), getRemoteShares())