Browse Source

fix(dav): multiple fixes in usage of webdav library

1. Refresh token on update
2. Fix some very weird imports
3. Patch fetch instead of request to prevent accessing impl details

Signed-off-by: Varun Patil <varunpatil@ucla.edu>
tags/v29.0.0beta1
Varun Patil 6 months ago
parent
commit
b03fd6e363

+ 16
- 9
apps/comments/src/services/DavClient.js View File

@@ -22,16 +22,23 @@

import { createClient } from 'webdav'
import { getRootPath } from '../utils/davUtils.js'
import { getRequestToken } from '@nextcloud/auth'
import { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'

// init webdav client
const client = createClient(getRootPath(), {
headers: {
// Add this so the server knows it is an request from the browser
'X-Requested-With': 'XMLHttpRequest',
// Inject user auth
requesttoken: getRequestToken() ?? '',
},
})
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

+ 4
- 6
apps/comments/src/services/GetComments.ts View File

@@ -23,8 +23,8 @@
import { parseXML, type DAVResult, type FileStat, type ResponseDataDetailed } from 'webdav'

// https://github.com/perry-mitchell/webdav-client/issues/339
import { processResponsePayload } from '../../../../node_modules/webdav/dist/node/response.js'
import { prepareFileFromProps } from '../../../../node_modules/webdav/dist/node/tools/dav.js'
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
@@ -77,10 +77,8 @@ const getDirectoryFiles = function(
// Map all items to a consistent output structure (results)
return responseItems.map(item => {
// Each item should contain a stat object
const {
propstat: { prop: props },
} = item
const props = item.propstat!.prop!;

return prepareFileFromProps(props, props.id.toString(), isDetailed)
return prepareFileFromProps(props, props.id!.toString(), isDetailed)
})
}

+ 19
- 11
apps/dav/src/dav/client.js View File

@@ -19,21 +19,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import * as webdav from 'webdav'
import axios from '@nextcloud/axios'
import { createClient } from 'webdav'
import memoize from 'lodash/fp/memoize.js'
import { generateRemoteUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'

export const getClient = memoize((service) => {
// Add this so the server knows it is an request from the browser
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
// init webdav client
const remote = generateRemoteUrl(`dav/${service}/${getCurrentUser().uid}`)
const client = createClient(remote)

// force our axios
const patcher = webdav.getPatcher()
patcher.patch('request', axios)
// 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 ?? '',
})
}

return webdav.createClient(
generateRemoteUrl(`dav/${service}/${getCurrentUser().uid}`)
)
// refresh headers when request token changes
onRequestTokenUpdate(setHeaders)
setHeaders(getRequestToken())

return client;
})

+ 24
- 14
apps/files/src/services/WebdavClient.ts View File

@@ -19,22 +19,30 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import type { RequestOptions, Response } from 'webdav'

import { createClient, getPatcher } from 'webdav'
import { generateRemoteUrl } from '@nextcloud/router'
import { getCurrentUser, getRequestToken } from '@nextcloud/auth'
import { request } from 'webdav/dist/node/request.js'
import { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'

export const rootPath = `/files/${getCurrentUser()?.uid}`
export const defaultRootUrl = generateRemoteUrl('dav' + rootPath)

export const getClient = (rootUrl = defaultRootUrl) => {
const client = createClient(rootUrl, {
headers: {
requesttoken: getRequestToken() || '',
},
})
const client = createClient(rootUrl)

// set CSRF token header
const setHeaders = (token: string | null) => {
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())

/**
* Allow to override the METHOD to support dav REPORT
@@ -45,12 +53,14 @@ export const getClient = (rootUrl = defaultRootUrl) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// https://github.com/perry-mitchell/hot-patcher/issues/6
patcher.patch('request', (options: RequestOptions): Promise<Response> => {
if (options.headers?.method) {
options.method = options.headers.method
delete options.headers.method
patcher.patch('fetch', (url: string, options: RequestInit): Promise<Response> => {
const headers = options.headers as Record<string, string>
if (headers?.method) {
options.method = headers.method
delete headers.method
}
return request(options)
return fetch(url, options)
})
return client

return client;
}

+ 19
- 6
apps/files_trashbin/src/services/client.ts View File

@@ -19,15 +19,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

import { createClient } from 'webdav'
import { generateRemoteUrl } from '@nextcloud/router'
import { getCurrentUser, getRequestToken } from '@nextcloud/auth'
import { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'

// init webdav client
export const rootPath = `/trashbin/${getCurrentUser()?.uid}/trash`
export const rootUrl = generateRemoteUrl('dav' + rootPath)
const client = createClient(rootUrl, {
headers: {
requesttoken: getRequestToken(),
},
})
const client = createClient(rootUrl)

// set CSRF token header
const setHeaders = (token: string | null) => {
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

+ 19
- 11
apps/files_versions/src/utils/davClient.js View File

@@ -21,17 +21,25 @@

import { createClient } from 'webdav'
import { generateRemoteUrl } from '@nextcloud/router'
import { getRequestToken } from '@nextcloud/auth'
import { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'

// init webdav client
const rootPath = 'dav'

// init webdav client on default dav endpoint
const remote = generateRemoteUrl(rootPath)
export default createClient(remote, {
headers: {
// Add this so the server knows it is an request from the browser
'X-Requested-With': 'XMLHttpRequest',
// Inject user auth
requesttoken: getRequestToken() ?? '',
},
})
const client = createClient(remote)

// 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

+ 16
- 6
apps/systemtags/src/services/davClient.ts View File

@@ -22,12 +22,22 @@

import { createClient } from 'webdav'
import { generateRemoteUrl } from '@nextcloud/router'
import { getRequestToken } from '@nextcloud/auth'
import { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'

// init webdav client
const rootUrl = generateRemoteUrl('dav')
export const davClient = createClient(rootUrl)

export const davClient = createClient(rootUrl, {
headers: {
requesttoken: getRequestToken() ?? '',
},
})
// set CSRF token header
const setHeaders = (token: string | null) => {
davClient.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())

+ 2
- 2
dist/comments-comments-app.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/comments-comments-app.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/comments-comments-tab.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/comments-comments-tab.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/core-common.js
File diff suppressed because it is too large
View File


+ 0
- 4
dist/core-common.js.LICENSE.txt View File

@@ -70,12 +70,8 @@

/*! @license DOMPurify 3.0.9 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.9/LICENSE */

/*! https://mths.be/punycode v1.4.1 by @mathias */

/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */

/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */

/**
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
*

+ 1
- 1
dist/core-common.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/dav-settings-personal-availability.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/dav-settings-personal-availability.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/files-init.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/files-init.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/files-main.js
File diff suppressed because it is too large
View File


+ 2
- 0
dist/files-main.js.LICENSE.txt View File

@@ -12,6 +12,8 @@

/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */

/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */

/**
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
*

+ 1
- 1
dist/files-main.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/files-sidebar.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/files-sidebar.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/files_trashbin-main.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/files_trashbin-main.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/files_versions-files_versions.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/files_versions-files_versions.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/systemtags-admin.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/systemtags-admin.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/systemtags-init.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/systemtags-init.js.map
File diff suppressed because it is too large
View File


+ 2
- 2
dist/theming-personal-theming.js
File diff suppressed because it is too large
View File


+ 2
- 0
dist/theming-personal-theming.js.LICENSE.txt View File

@@ -1,3 +1,5 @@
/*! https://mths.be/punycode v1.4.1 by @mathias */

/**
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
*

+ 1
- 1
dist/theming-personal-theming.js.map
File diff suppressed because it is too large
View File


Loading…
Cancel
Save