aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/src
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2024-09-01 00:37:56 +0200
committerFerdinand Thiessen <opensource@fthiessen.de>2024-09-02 17:48:46 +0200
commit8770e2b282960cdb0878f5fc768b2876981d13ab (patch)
treee6ece1b644005f3ac156ec1971e1c6bc74ec3dbd /apps/files_sharing/src
parent69f4a397d1b68ccc182d976dfce10823ff20cb5f (diff)
downloadnextcloud-server-8770e2b282960cdb0878f5fc768b2876981d13ab.tar.gz
nextcloud-server-8770e2b282960cdb0878f5fc768b2876981d13ab.zip
fix(files): Correctly parse external shares for files UI
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Diffstat (limited to 'apps/files_sharing/src')
-rw-r--r--apps/files_sharing/src/services/SharingService.spec.ts48
-rw-r--r--apps/files_sharing/src/services/SharingService.ts27
2 files changed, 65 insertions, 10 deletions
diff --git a/apps/files_sharing/src/services/SharingService.spec.ts b/apps/files_sharing/src/services/SharingService.spec.ts
index bd0e018db7a..ab0a5163618 100644
--- a/apps/files_sharing/src/services/SharingService.spec.ts
+++ b/apps/files_sharing/src/services/SharingService.spec.ts
@@ -277,6 +277,25 @@ describe('SharingService share to Node mapping', () => {
tags: [TAG_FAVORITE],
}
+ const remoteFile = {
+ mimetype: 'text/markdown',
+ mtime: 1688721600,
+ permissions: 19,
+ type: 'file',
+ file_id: 1234,
+ id: 4,
+ share_type: ShareType.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,
+ }
+
beforeEach(() => { vi.resetAllMocks() })
test('File', async () => {
@@ -338,6 +357,35 @@ describe('SharingService share to Node mapping', () => {
expect(folder.attributes.favorite).toBe(1)
})
+ test('Remote file', async () => {
+ 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://nextcloud.local/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 () => {
vi.spyOn(logger, 'error').mockImplementationOnce(() => {})
axios.get.mockReturnValueOnce(Promise.resolve({
diff --git a/apps/files_sharing/src/services/SharingService.ts b/apps/files_sharing/src/services/SharingService.ts
index 4206e4a305a..e168f202fba 100644
--- a/apps/files_sharing/src/services/SharingService.ts
+++ b/apps/files_sharing/src/services/SharingService.ts
@@ -26,10 +26,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
@@ -46,14 +52,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)
}
@@ -75,7 +82,7 @@ const ocsEntryToNode = async function(ocsEntry: any): Promise<Folder | File | nu
'owner-display-name': ocsEntry?.displayname_owner,
'share-types': ocsEntry?.share_type,
'share-attributes': ocsEntry?.attributes || '[]',
- favorite: ocsEntry?.tags?.includes((window.OC as Nextcloud.v28.OC & { TAG_FAVORITE: string }).TAG_FAVORITE) ? 1 : 0,
+ favorite: ocsEntry?.tags?.includes((window.OC as Nextcloud.v29.OC & { TAG_FAVORITE: string }).TAG_FAVORITE) ? 1 : 0,
},
})
} catch (error) {
@@ -164,8 +171,8 @@ export const isFileRequest = (attributes = '[]'): boolean => {
/**
* Group an array of objects (here Nodes) by a key
* and return an array of arrays of them.
- * @param nodes
- * @param key
+ * @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) {