aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/src/services/SharingService.ts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_sharing/src/services/SharingService.ts')
-rw-r--r--apps/files_sharing/src/services/SharingService.ts183
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,
+ }
+}