Skip to content

Commit a3c6fe7

Browse files
susnuxAntreesy
authored andcommitted
fix(files): Correctly parse external shares for files UI
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 8f7f54b commit a3c6fe7

2 files changed

Lines changed: 65 additions & 8 deletions

File tree

apps/files_sharing/src/services/SharingService.spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,25 @@ describe('SharingService share to Node mapping', () => {
287287
tags: [window.OC.TAG_FAVORITE],
288288
}
289289

290+
const remoteFile = {
291+
mimetype: 'text/markdown',
292+
mtime: 1688721600,
293+
permissions: 19,
294+
type: 'file',
295+
file_id: 1234,
296+
id: 4,
297+
share_type: Type.SHARE_TYPE_USER,
298+
parent: null,
299+
remote: 'http://exampe.com',
300+
remote_id: '12345',
301+
share_token: 'share-token',
302+
name: '/test.md',
303+
mountpoint: '/shares/test.md',
304+
owner: 'owner-uid',
305+
user: 'sharee-uid',
306+
accepted: true,
307+
}
308+
290309
test('File', async () => {
291310
jest.spyOn(axios, 'get').mockReturnValueOnce(Promise.resolve({
292311
data: {
@@ -346,6 +365,35 @@ describe('SharingService share to Node mapping', () => {
346365
expect(folder.attributes.favorite).toBe(1)
347366
})
348367

368+
test('Remote file', async () => {
369+
jest.spyOn(axios, 'get').mockReturnValueOnce(Promise.resolve({
370+
data: {
371+
ocs: {
372+
data: [remoteFile],
373+
},
374+
},
375+
}))
376+
377+
const shares = await getContents(false, true, false, false)
378+
379+
expect(axios.get).toHaveBeenCalledTimes(1)
380+
expect(shares.contents).toHaveLength(1)
381+
382+
const file = shares.contents[0] as File
383+
expect(file).toBeInstanceOf(File)
384+
expect(file.fileid).toBe(1234)
385+
expect(file.source).toBe('http://localhost/remote.php/dav/files/test/shares/test.md')
386+
expect(file.owner).toBe('owner-uid')
387+
expect(file.mime).toBe('text/markdown')
388+
expect(file.mtime?.getTime()).toBe(remoteFile.mtime * 1000)
389+
// not available for remote shares
390+
expect(file.size).toBe(undefined)
391+
expect(file.permissions).toBe(0)
392+
expect(file.root).toBe('/files/test')
393+
expect(file.attributes).toBeInstanceOf(Object)
394+
expect(file.attributes.favorite).toBe(0)
395+
})
396+
349397
test('Empty', async () => {
350398
jest.spyOn(logger, 'error').mockImplementationOnce(() => {})
351399
jest.spyOn(axios, 'get').mockReturnValueOnce(Promise.resolve({

apps/files_sharing/src/services/SharingService.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,16 @@ const ocsEntryToNode = async function(ocsEntry: any): Promise<Folder | File | nu
5050
try {
5151
// Federated share handling
5252
if (ocsEntry?.remote_id !== undefined) {
53-
const mime = (await import('mime')).default
54-
// This won't catch files without an extension, but this is the best we can do
55-
ocsEntry.mimetype = mime.getType(ocsEntry.name)
56-
ocsEntry.item_type = ocsEntry.mimetype ? 'file' : 'folder'
53+
if (!ocsEntry.mimetype) {
54+
const mime = (await import('mime')).default
55+
// This won't catch files without an extension, but this is the best we can do
56+
ocsEntry.mimetype = mime.getType(ocsEntry.name)
57+
}
58+
ocsEntry.item_type = ocsEntry.type || (ocsEntry.mimetype ? 'file' : 'folder')
59+
60+
// different naming for remote shares
61+
ocsEntry.item_mtime = ocsEntry.mtime
62+
ocsEntry.file_target = ocsEntry.file_target || ocsEntry.mountpoint
5763

5864
// Need to set permissions to NONE for federated shares
5965
ocsEntry.item_permissions = Permission.NONE
@@ -70,14 +76,15 @@ const ocsEntryToNode = async function(ocsEntry: any): Promise<Folder | File | nu
7076

7177
// If this is an external share that is not yet accepted,
7278
// we don't have an id. We can fallback to the row id temporarily
73-
const fileid = ocsEntry.file_source || ocsEntry.id
79+
// local shares (this server) use `file_source`, but remote shares (federated) use `file_id`
80+
const fileid = ocsEntry.file_source || ocsEntry.file_id || ocsEntry.id
7481

7582
// Generate path and strip double slashes
76-
const path = ocsEntry?.path || ocsEntry.file_target || ocsEntry.name
83+
const path = ocsEntry.path || ocsEntry.file_target || ocsEntry.name
7784
const source = generateRemoteUrl(`dav/${rootPath}/${path}`.replaceAll(/\/\//gm, '/'))
7885

86+
let mtime = ocsEntry.item_mtime ? new Date((ocsEntry.item_mtime) * 1000) : undefined
7987
// Prefer share time if more recent than item mtime
80-
let mtime = ocsEntry?.item_mtime ? new Date((ocsEntry.item_mtime) * 1000) : undefined
8188
if (ocsEntry?.stime > (ocsEntry?.item_mtime || 0)) {
8289
mtime = new Date((ocsEntry.stime) * 1000)
8390
}
@@ -169,6 +176,8 @@ const getDeletedShares = function(): AxiosPromise<OCSResponse<any>> {
169176
/**
170177
* Group an array of objects (here Nodes) by a key
171178
* and return an array of arrays of them.
179+
* @param nodes Nodes to group
180+
* @param key The attribute to group by
172181
*/
173182
const groupBy = function(nodes: (Folder | File)[], key: string) {
174183
return Object.values(nodes.reduce(function(acc, curr) {
@@ -178,7 +187,7 @@ const groupBy = function(nodes: (Folder | File)[], key: string) {
178187
}
179188

180189
export const getContents = async (sharedWithYou = true, sharedWithOthers = true, pendingShares = false, deletedshares = false, filterTypes: number[] = []): Promise<ContentsWithRoot> => {
181-
const promises = [] as AxiosPromise<OCSResponse<any>>[]
190+
const promises = [] as AxiosPromise<OCSResponse<unknown>>[]
182191

183192
if (sharedWithYou) {
184193
promises.push(getSharedWithYou(), getRemoteShares())

0 commit comments

Comments
 (0)