From 31aaf80f00410cfb290eecb01c3dbd82756b1791 Mon Sep 17 00:00:00 2001 From: the-djmaze <> Date: Mon, 14 Nov 2022 12:35:42 +0100 Subject: [PATCH] Share public/internal file link #569 --- plugins/nextcloud/index.php | 4 +- plugins/nextcloud/js/composer.js | 1 + plugins/nextcloud/js/webdav.js | 111 +++++++++++++------------------ 3 files changed, 49 insertions(+), 67 deletions(-) diff --git a/plugins/nextcloud/index.php b/plugins/nextcloud/index.php index e6c45565f..2c541439d 100644 --- a/plugins/nextcloud/index.php +++ b/plugins/nextcloud/index.php @@ -4,8 +4,8 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin { const NAME = 'Nextcloud', - VERSION = '2.10', - RELEASE = '2022-11-04', + VERSION = '2.11', + RELEASE = '2022-11-14', CATEGORY = 'Integrations', DESCRIPTION = 'Integrate with Nextcloud v20+', REQUIRED = '2.19.0'; diff --git a/plugins/nextcloud/js/composer.js b/plugins/nextcloud/js/composer.js index b53611dc2..7ee5f015d 100644 --- a/plugins/nextcloud/js/composer.js +++ b/plugins/nextcloud/js/composer.js @@ -29,6 +29,7 @@ } ); } else if (file.url) { + // TODO: other editors and text/plain view.oEditor.editor.squire.makeLink(file.url); } }); diff --git a/plugins/nextcloud/js/webdav.js b/plugins/nextcloud/js/webdav.js index 824926b7b..d45cdef55 100644 --- a/plugins/nextcloud/js/webdav.js +++ b/plugins/nextcloud/js/webdav.js @@ -10,6 +10,7 @@ const OC = () => parent.OC, // Nextcloud 19 deprecated generateUrl, but screw `import { generateUrl } from "@nextcloud/router"` + shareUrl = () => OC().webroot + '/ocs/v2.php/apps/files_sharing/api/v1/shares', generateUrl = path => OC().webroot + (OC().config.modRewriteWorking ? '' : '/index.php') + path, generateRemoteUrl = path => location.protocol + '//' + location.host + generateUrl(path), @@ -22,36 +23,10 @@ const - - - - - `, -/* - - - video/mp4 - RGDNVW - 3963036 - 19 - [] - - 3 - - - HTTP/1.1 200 OK - - - - - - HTTP/1.1 404 Not Found - -*/ propfindCal = ` @@ -70,11 +45,10 @@ const getDavElementByTagName = (parent, localName) => getDavElementsByTagName(parent, localName)?.item(0), getElementByTagName = (parent, localName) => +parent.getElementsByTagName(localName)?.item(0), - davFetch = (mode, path, options) => { + ncFetch = (path, options) => { if (!OC().requestToken) { return Promise.reject(new Error('OC.requestToken missing')); } - let cfg = rl.settings.get('Nextcloud'); options = Object.assign({ mode: 'same-origin', cache: 'no-cache', @@ -83,8 +57,13 @@ const headers: {} }, options); options.headers.requesttoken = OC().requestToken; + return fetch(path, options); + }, + + davFetch = (mode, path, options) => { + let cfg = rl.settings.get('Nextcloud'); // cfg.UID = document.head.dataset.user - return fetch(cfg.WebDAV + '/' + mode + '/' + cfg.UID + path, options); + return ncFetch(cfg.WebDAV + '/' + mode + '/' + cfg.UID + path, options); }, davFetchFiles = (path, options) => davFetch('files', path, options), @@ -129,6 +108,7 @@ const elem.id = e.getElementsByTagNameNS(nsOC, 'fileid')?.item(0)?.textContent; elem.size = getDavElementByTagName(e, 'getcontentlength')?.textContent || getElementByTagName(e, 'oc:size')?.textContent; + elem.shared = [...e.getElementsByTagNameNS(nsOC, 'share-type')].some(node => '3' == node.textContent); } elemList.push(elem); } @@ -176,7 +156,7 @@ const li.dataset.icon = '🗎'; btn.name = 'select'; - btn.textContent = 'select'; + btn.textContent = '📎 attach'; btn.className = 'button-vue'; li.append(btn); @@ -185,13 +165,13 @@ const btn.textContent = '🔗 internal'; btn.className = 'button-vue'; li.append(btn); -/* + btn = document.createElement('button'); btn.name = 'share-public'; btn.textContent = '🔗 public'; btn.className = 'button-vue'; li.append(btn); -*/ + parent.append(li); } }); @@ -225,46 +205,47 @@ class NextcloudFilesPopupView extends rl.pluginPopupView { this.tree.addEventListener('click', event => { let el = event.target; if (el.matches('button')) { - let parent = el.parentNode; + let parent = el.parentNode, + item = parent.item; if ('select' == el.name) { - this.select = this.files() ? [parent.item] : parent.item_name; + this.select = this.files() ? [item] : parent.item_name; this.close(); } else if ('share-internal' == el.name) { - this.select = [{url:generateRemoteUrl(`/f/${parent.item.id}`)}]; + this.select = [{url:generateRemoteUrl(`/f/${item.id}`)}]; this.close(); } else if ('share-public' == el.name) { -/* - if (3 == share-type) { - GET generateUrl(`/ocs/v2.php/apps/files_sharing/api/v1/shares?format=json&path=${encodeURIComponent(parent.item.name)}&reshares=true`); + if (item.shared) { + ncFetch( + shareUrl() + `?format=json&path=${encodeURIComponent(item.name)}&reshares=true` + ) + .then(response => (response.status < 400) ? response.json() : Promise.reject(new Error({ response }))) + .then(json => { + this.select = [{url:json.ocs.data[0].url}]; + this.close(); +// json.data[0].password + }); } else { - POST generateUrl(`/ocs/v2.php/apps/files_sharing/api/v1/shares`) - > {"path":"/Nextcloud intro.mp4","shareType":3,"attributes":"[]"} - < {"ocs":{"meta":{"status":"ok","statuscode":200,"message":"OK"}, - "data":{ - "id":"2", - "share_type":3, - "permissions":17, - "token":"7GK9mL9LCTseSgK", - "path":"\/Nextcloud intro.mp4", - "item_type":"file", - "mimetype":"video\/mp4", - "storage":1, - "item_source":20, - "file_source":20, - "file_parent":2, - "file_target":"\/Nextcloud intro.mp4", - "password":null, - "url":"https:\/\/example.com\/index.php\/s\/7GK9mL9LCTseSgK", - "mail_send":1, - "hide_download":0, - "attributes":null - }}} - GET /index.php/s/7GK9mL9LCTseSgK - PUT /ocs/v2.php/apps/files_sharing/api/v1/shares/2 - > {"expireDate":"\"2022-11-29T23:00:00.000Z\""} - > {"password":"ABC09"} + ncFetch( + shareUrl(), + { + method:'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + path:item.name, + shareType:3, + attributes:"[]" + }) + } + ) + .then(response => (response.status < 400) ? response.json() : Promise.reject(new Error({ response }))) + .then(json => { + this.select = [{url:json.ocs.data.url}]; + this.close(); + }); } -*/ } else if ('create' == el.name) { let name = el.input.value.replace(/[|\\?*<":>+[]\/&\s]/g, ''); if (name.length) {