diff options
Diffstat (limited to 'apps/files_sharing/src/services/SharingService.ts')
-rw-r--r-- | apps/files_sharing/src/services/SharingService.ts | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/apps/files_sharing/src/services/SharingService.ts b/apps/files_sharing/src/services/SharingService.ts new file mode 100644 index 00000000000..036eae07bce --- /dev/null +++ b/apps/files_sharing/src/services/SharingService.ts @@ -0,0 +1,183 @@ +/** + * @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.com> + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +/* eslint-disable camelcase, n/no-extraneous-import */ +import type { AxiosPromise } from 'axios' +import type { ContentsWithRoot } from '../../../files/src/services/Navigation' + +import { Folder, File } from '@nextcloud/files' +import { generateOcsUrl, generateRemoteUrl, generateUrl } from '@nextcloud/router' +import { getCurrentUser } from '@nextcloud/auth' +import { rootPath } from '../../../files/src/services/WebdavClient' +import axios from '@nextcloud/axios' +import logger from './logger' + +type OCSResponse = { + ocs: { + meta: { + status: string + statuscode: number + message: string + }, + data: [] + } +} + +const headers = { + 'Content-Type': 'application/json', +} + +const ocsEntryToNode = function(ocsEntry: any): Folder | File | null { + try { + const Node = ocsEntry?.item_type === 'folder' ? Folder : File + + // Sometimes it's an int, sometimes it contains the identifier like "ocinternal:123" + const fileid = ocsEntry.file_source + const previewUrl = generateUrl('/core/preview?fileId={fileid}&x=32&y=32&forceIcon=0', { fileid }) + + // Generate path and strip double slashes + const path = ocsEntry?.path || ocsEntry.file_target + const source = generateRemoteUrl(`dav/${rootPath}/${path}`.replace(/\/\//, '/')) + + // Prefer share time if more recent than mtime + let mtime = ocsEntry?.mtime ? new Date((ocsEntry.mtime) * 1000) : undefined + if (ocsEntry?.stime > (ocsEntry?.mtime || 0)) { + mtime = new Date((ocsEntry.stime) * 1000) + } + + return new Node({ + id: fileid, + source, + owner: ocsEntry?.uid_owner, + mime: ocsEntry?.mimetype, + mtime, + size: ocsEntry?.size || undefined, + permissions: ocsEntry?.permissions, + root: rootPath, + attributes: { + ...ocsEntry, + previewUrl, + favorite: ocsEntry?.tags?.includes(window.OC.TAG_FAVORITE) ? 1 : 0, + }, + }) + } catch (error) { + logger.error('Error while parsing OCS entry', error) + return null + } +} + +const getShares = function(shared_with_me = false): AxiosPromise<OCSResponse> { + const url = generateOcsUrl('apps/files_sharing/api/v1/shares') + return axios({ + url, + headers, + params: { + shared_with_me, + include_tags: true, + }, + }) +} + +const getSharedWithYou = function(): AxiosPromise<OCSResponse> { + return getShares(true) +} + +const getSharedWithOthers = function(): AxiosPromise<OCSResponse> { + return getShares(false) +} + +const getRemoteShares = function(): AxiosPromise<OCSResponse> { + const url = generateOcsUrl('apps/files_sharing/api/v1/remote_shares') + return axios({ + url, + headers, + params: { + include_tags: true, + }, + }) +} + +const getPendingShares = function(): AxiosPromise<OCSResponse> { + const url = generateOcsUrl('apps/files_sharing/api/v1/shares/pending') + return axios({ + url, + headers, + params: { + include_tags: true, + }, + }) +} + +const getRemotePendingShares = function(): AxiosPromise<OCSResponse> { + const url = generateOcsUrl('apps/files_sharing/api/v1/remote_shares/pending') + return axios({ + url, + headers, + params: { + include_tags: true, + }, + }) +} + +const getDeletedShares = function(): AxiosPromise<OCSResponse> { + const url = generateOcsUrl('apps/files_sharing/api/v1/deletedshares') + return axios({ + url, + headers, + params: { + include_tags: true, + }, + }) +} + +export const getContents = async (sharedWithYou = true, sharedWithOthers = true, pendingShares = false, deletedshares = false, filterTypes: number[] = []): Promise<ContentsWithRoot> => { + const promises = [] as AxiosPromise<OCSResponse>[] + + if (sharedWithYou) { + promises.push(getSharedWithYou(), getRemoteShares()) + } + if (sharedWithOthers) { + promises.push(getSharedWithOthers()) + } + if (pendingShares) { + promises.push(getPendingShares(), getRemotePendingShares()) + } + if (deletedshares) { + promises.push(getDeletedShares()) + } + + const responses = await Promise.all(promises) + const data = responses.map((response) => response.data.ocs.data).flat() + let contents = data.map(ocsEntryToNode).filter((node) => node !== null) as (Folder | File)[] + + if (filterTypes.length > 0) { + contents = contents.filter((node) => filterTypes.includes(node.attributes?.share_type)) + } + + return { + folder: new Folder({ + id: 0, + source: generateRemoteUrl('dav' + rootPath), + owner: getCurrentUser()?.uid || '', + }), + contents, + } +} |