aboutsummaryrefslogtreecommitdiffstats
path: root/apps/comments/src/services
diff options
context:
space:
mode:
Diffstat (limited to 'apps/comments/src/services')
-rw-r--r--apps/comments/src/services/CommentsInstance.js58
-rw-r--r--apps/comments/src/services/DavClient.js49
-rw-r--r--apps/comments/src/services/DeleteComment.js31
-rw-r--r--apps/comments/src/services/EditComment.js31
-rw-r--r--apps/comments/src/services/GetComments.js104
-rw-r--r--apps/comments/src/services/GetComments.ts67
-rw-r--r--apps/comments/src/services/NewComment.js49
-rw-r--r--apps/comments/src/services/ReadComments.ts38
8 files changed, 180 insertions, 247 deletions
diff --git a/apps/comments/src/services/CommentsInstance.js b/apps/comments/src/services/CommentsInstance.js
index f5263f35c3d..cc45d0cbea7 100644
--- a/apps/comments/src/services/CommentsInstance.js
+++ b/apps/comments/src/services/CommentsInstance.js
@@ -1,34 +1,18 @@
/**
- * @copyright Copyright (c) 2020 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/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import { getLoggerBuilder } from '@nextcloud/logger'
-import { translate as t, translatePlural as n } from '@nextcloud/l10n'
-import CommentsApp from '../views/Comments'
+import { getCSPNonce } from '@nextcloud/auth'
+import { t, n } from '@nextcloud/l10n'
+import { PiniaVuePlugin, createPinia } from 'pinia'
import Vue from 'vue'
+import CommentsApp from '../views/Comments.vue'
+import logger from '../logger.js'
-const logger = getLoggerBuilder()
- .setApp('comments')
- .detectUser()
- .build()
+Vue.use(PiniaVuePlugin)
+// eslint-disable-next-line camelcase
+__webpack_nonce__ = getCSPNonce()
// Add translates functions
Vue.mixin({
@@ -48,19 +32,21 @@ export default class CommentInstance {
/**
* Initialize a new Comments instance for the desired type
*
- * @param {string} commentsType the comments endpoint type
+ * @param {string} resourceType the comments endpoint type
* @param {object} options the vue options (propsData, parent, el...)
*/
- constructor(commentsType = 'files', options) {
- // Add comments type as a global mixin
- Vue.mixin({
- data() {
- return {
- commentsType,
- }
- },
- })
+ constructor(resourceType = 'files', options = {}) {
+ const pinia = createPinia()
+ // Merge options and set `resourceType` property
+ options = {
+ ...options,
+ propsData: {
+ ...(options.propsData ?? {}),
+ resourceType,
+ },
+ pinia,
+ }
// Init Comments component
const View = Vue.extend(CommentsApp)
return new View(options)
diff --git a/apps/comments/src/services/DavClient.js b/apps/comments/src/services/DavClient.js
index ee5aec129c1..3e9a529283f 100644
--- a/apps/comments/src/services/DavClient.js
+++ b/apps/comments/src/services/DavClient.js
@@ -1,38 +1,27 @@
/**
- * @copyright Copyright (c) 2021 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/>.
- *
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import { createClient, getPatcher } from 'webdav'
-import axios from '@nextcloud/axios'
-
-import { getRootPath } from '../utils/davUtils'
-
-// Add this so the server knows it is an request from the browser
-axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
-
-// force our axios
-const patcher = getPatcher()
-patcher.patch('request', axios)
+import { createClient } from 'webdav'
+import { getRootPath } from '../utils/davUtils.js'
+import { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
// init webdav client
const client = createClient(getRootPath())
+// set CSRF token header
+const setHeaders = (token) => {
+ client.setHeaders({
+ // Add this so the server knows it is an request from the browser
+ 'X-Requested-With': 'XMLHttpRequest',
+ // Inject user auth
+ requesttoken: token ?? '',
+ })
+}
+
+// refresh headers when request token changes
+onRequestTokenUpdate(setHeaders)
+setHeaders(getRequestToken())
+
export default client
diff --git a/apps/comments/src/services/DeleteComment.js b/apps/comments/src/services/DeleteComment.js
index 871f6b6c5b8..1ed63d7836a 100644
--- a/apps/comments/src/services/DeleteComment.js
+++ b/apps/comments/src/services/DeleteComment.js
@@ -1,36 +1,19 @@
/**
- * @copyright Copyright (c) 2020 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/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import client from './DavClient'
+import client from './DavClient.js'
/**
* Delete a comment
*
- * @param {string} commentsType the ressource type
- * @param {number} ressourceId the ressource ID
+ * @param {string} resourceType the resource type
+ * @param {number} resourceId the resource ID
* @param {number} commentId the comment iD
*/
-export default async function(commentsType, ressourceId, commentId) {
- const commentPath = ['', commentsType, ressourceId, commentId].join('/')
+export default async function(resourceType, resourceId, commentId) {
+ const commentPath = ['', resourceType, resourceId, commentId].join('/')
// Fetch newly created comment data
await client.deleteFile(commentPath)
diff --git a/apps/comments/src/services/EditComment.js b/apps/comments/src/services/EditComment.js
index f3a2d857356..4ec33415a72 100644
--- a/apps/comments/src/services/EditComment.js
+++ b/apps/comments/src/services/EditComment.js
@@ -1,37 +1,20 @@
/**
- * @copyright Copyright (c) 2020 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/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import client from './DavClient'
+import client from './DavClient.js'
/**
* Edit an existing comment
*
- * @param {string} commentsType the ressource type
- * @param {number} ressourceId the ressource ID
+ * @param {string} resourceType the resource type
+ * @param {number} resourceId the resource ID
* @param {number} commentId the comment iD
* @param {string} message the message content
*/
-export default async function(commentsType, ressourceId, commentId, message) {
- const commentPath = ['', commentsType, ressourceId, commentId].join('/')
+export default async function(resourceType, resourceId, commentId, message) {
+ const commentPath = ['', resourceType, resourceId, commentId].join('/')
return await client.customRequest(commentPath, Object.assign({
method: 'PROPPATCH',
diff --git a/apps/comments/src/services/GetComments.js b/apps/comments/src/services/GetComments.js
deleted file mode 100644
index 4d1f7b022ae..00000000000
--- a/apps/comments/src/services/GetComments.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * @copyright Copyright (c) 2020 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/>.
- *
- */
-
-import { parseXML, prepareFileFromProps } from 'webdav/dist/node/tools/dav'
-import { processResponsePayload } from 'webdav/dist/node/response'
-import client from './DavClient'
-
-export const DEFAULT_LIMIT = 20
-/**
- * Retrieve the comments list
- *
- * @param {object} data destructuring object
- * @param {string} data.commentsType the ressource type
- * @param {number} data.ressourceId the ressource ID
- * @param {object} [options] optional options for axios
- * @return {object[]} the comments list
- */
-export default async function({ commentsType, ressourceId }, options = {}) {
- let response = null
- const ressourcePath = ['', commentsType, ressourceId].join('/')
-
- return await client.customRequest(ressourcePath, Object.assign({
- method: 'REPORT',
- data: `<?xml version="1.0"?>
- <oc:filter-comments
- xmlns:d="DAV:"
- xmlns:oc="http://owncloud.org/ns"
- xmlns:nc="http://nextcloud.org/ns"
- xmlns:ocs="http://open-collaboration-services.org/ns">
- <oc:limit>${DEFAULT_LIMIT}</oc:limit>
- <oc:offset>${options.offset || 0}</oc:offset>
- </oc:filter-comments>`,
- }, options))
- // See example on how it's done normaly
- // https://github.com/perry-mitchell/webdav-client/blob/9de2da4a2599e06bd86c2778145b7ade39fe0b3c/source/interface/stat.js#L19
- // Waiting for proper REPORT integration https://github.com/perry-mitchell/webdav-client/issues/207
- .then(res => {
- response = res
- return res.data
- })
- .then(parseXML)
- .then(xml => processMultistatus(xml, true))
- .then(comments => processResponsePayload(response, comments, true))
- .then(response => response.data)
-}
-
-// https://github.com/perry-mitchell/webdav-client/blob/9de2da4a2599e06bd86c2778145b7ade39fe0b3c/source/interface/directoryContents.js#L32
-/**
- * @param {any} result -
- * @param {any} isDetailed -
- */
-function processMultistatus(result, isDetailed = false) {
- // Extract the response items (directory contents)
- const {
- multistatus: { response: responseItems },
- } = result
- return responseItems.map(item => {
- // Each item should contain a stat object
- const {
- propstat: { prop: props },
- } = item
- // Decode HTML entities
- const decodedProps = {
- ...props,
- // Decode twice to handle potentially double-encoded entities
- // FIXME Remove this once https://github.com/nextcloud/server/issues/29306 is resolved
- actorDisplayName: decodeHtmlEntities(props.actorDisplayName, 2),
- message: decodeHtmlEntities(props.message, 2),
- }
- return prepareFileFromProps(decodedProps, decodedProps.id.toString(), isDetailed)
- })
-}
-
-/**
- * @param {any} value -
- * @param {any} passes -
- */
-function decodeHtmlEntities(value, passes = 1) {
- const parser = new DOMParser()
- let decoded = value
- for (let i = 0; i < passes; i++) {
- decoded = parser.parseFromString(decoded, 'text/html').documentElement.textContent
- }
- return decoded
-}
diff --git a/apps/comments/src/services/GetComments.ts b/apps/comments/src/services/GetComments.ts
new file mode 100644
index 00000000000..c42aa21d6cb
--- /dev/null
+++ b/apps/comments/src/services/GetComments.ts
@@ -0,0 +1,67 @@
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { parseXML, type DAVResult, type FileStat, type ResponseDataDetailed } from 'webdav'
+
+// https://github.com/perry-mitchell/webdav-client/issues/339
+import { processResponsePayload } from 'webdav/dist/node/response.js'
+import { prepareFileFromProps } from 'webdav/dist/node/tools/dav.js'
+import client from './DavClient.js'
+
+export const DEFAULT_LIMIT = 20
+
+/**
+ * Retrieve the comments list
+ *
+ * @param {object} data destructuring object
+ * @param {string} data.resourceType the resource type
+ * @param {number} data.resourceId the resource ID
+ * @param {object} [options] optional options for axios
+ * @param {number} [options.offset] the pagination offset
+ * @param {number} [options.limit] the pagination limit, defaults to 20
+ * @param {Date} [options.datetime] optional date to query
+ * @return {{data: object[]}} the comments list
+ */
+export const getComments = async function({ resourceType, resourceId }, options: { offset: number, limit?: number, datetime?: Date }) {
+ const resourcePath = ['', resourceType, resourceId].join('/')
+ const datetime = options.datetime ? `<oc:datetime>${options.datetime.toISOString()}</oc:datetime>` : ''
+ const response = await client.customRequest(resourcePath, Object.assign({
+ method: 'REPORT',
+ data: `<?xml version="1.0"?>
+ <oc:filter-comments
+ xmlns:d="DAV:"
+ xmlns:oc="http://owncloud.org/ns"
+ xmlns:nc="http://nextcloud.org/ns"
+ xmlns:ocs="http://open-collaboration-services.org/ns">
+ <oc:limit>${options.limit ?? DEFAULT_LIMIT}</oc:limit>
+ <oc:offset>${options.offset || 0}</oc:offset>
+ ${datetime}
+ </oc:filter-comments>`,
+ }, options))
+
+ const responseData = await response.text()
+ const result = await parseXML(responseData)
+ const stat = getDirectoryFiles(result, true)
+ return processResponsePayload(response, stat, true) as ResponseDataDetailed<FileStat[]>
+}
+
+// https://github.com/perry-mitchell/webdav-client/blob/8d9694613c978ce7404e26a401c39a41f125f87f/source/operations/directoryContents.ts
+const getDirectoryFiles = function(
+ result: DAVResult,
+ isDetailed = false,
+): Array<FileStat> {
+ // Extract the response items (directory contents)
+ const {
+ multistatus: { response: responseItems },
+ } = result
+
+ // Map all items to a consistent output structure (results)
+ return responseItems.map(item => {
+ // Each item should contain a stat object
+ const props = item.propstat!.prop!
+
+ return prepareFileFromProps(props, props.id!.toString(), isDetailed)
+ })
+}
diff --git a/apps/comments/src/services/NewComment.js b/apps/comments/src/services/NewComment.js
index eaf08cc10b9..663b4d72e02 100644
--- a/apps/comments/src/services/NewComment.js
+++ b/apps/comments/src/services/NewComment.js
@@ -1,59 +1,50 @@
/**
- * @copyright Copyright (c) 2020 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/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { getCurrentUser } from '@nextcloud/auth'
-import { getRootPath } from '../utils/davUtils'
+import { getRootPath } from '../utils/davUtils.js'
+import { decodeHtmlEntities } from '../utils/decodeHtmlEntities.js'
import axios from '@nextcloud/axios'
-import client from './DavClient'
+import client from './DavClient.js'
/**
* Retrieve the comments list
*
- * @param {string} commentsType the ressource type
- * @param {number} ressourceId the ressource ID
+ * @param {string} resourceType the resource type
+ * @param {number} resourceId the resource ID
* @param {string} message the message
* @return {object} the new comment
*/
-export default async function(commentsType, ressourceId, message) {
- const ressourcePath = ['', commentsType, ressourceId].join('/')
+export default async function(resourceType, resourceId, message) {
+ const resourcePath = ['', resourceType, resourceId].join('/')
- const response = await axios.post(getRootPath() + ressourcePath, {
+ const response = await axios.post(getRootPath() + resourcePath, {
actorDisplayName: getCurrentUser().displayName,
actorId: getCurrentUser().uid,
actorType: 'users',
creationDateTime: (new Date()).toUTCString(),
message,
- objectType: 'files',
+ objectType: resourceType,
verb: 'comment',
})
- // Retrieve comment id from ressource location
+ // Retrieve comment id from resource location
const commentId = parseInt(response.headers['content-location'].split('/').pop())
- const commentPath = ressourcePath + '/' + commentId
+ const commentPath = resourcePath + '/' + commentId
// Fetch newly created comment data
const comment = await client.stat(commentPath, {
details: true,
})
+ const props = comment.data.props
+ // Decode twice to handle potentially double-encoded entities
+ // FIXME Remove this once https://github.com/nextcloud/server/issues/29306
+ // is resolved
+ props.actorDisplayName = decodeHtmlEntities(props.actorDisplayName, 2)
+ props.message = decodeHtmlEntities(props.message, 2)
+
return comment.data
}
diff --git a/apps/comments/src/services/ReadComments.ts b/apps/comments/src/services/ReadComments.ts
new file mode 100644
index 00000000000..73682e21d95
--- /dev/null
+++ b/apps/comments/src/services/ReadComments.ts
@@ -0,0 +1,38 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import client from './DavClient.js'
+
+import type { Response } from 'webdav'
+
+/**
+ * Mark comments older than the date timestamp as read
+ *
+ * @param resourceType the resource type
+ * @param resourceId the resource ID
+ * @param date the date object
+ */
+export const markCommentsAsRead = (
+ resourceType: string,
+ resourceId: number,
+ date: Date,
+): Promise<Response> => {
+ const resourcePath = ['', resourceType, resourceId].join('/')
+ const readMarker = date.toUTCString()
+
+ return client.customRequest(resourcePath, {
+ method: 'PROPPATCH',
+ data: `<?xml version="1.0"?>
+ <d:propertyupdate
+ xmlns:d="DAV:"
+ xmlns:oc="http://owncloud.org/ns">
+ <d:set>
+ <d:prop>
+ <oc:readMarker>${readMarker}</oc:readMarker>
+ </d:prop>
+ </d:set>
+ </d:propertyupdate>`,
+ })
+}