mirror of https://github.com/nextcloud/server
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>
This commit is contained in:
parent
dfd42307f0
commit
b03fd6e363
|
@ -22,16 +22,23 @@
|
||||||
|
|
||||||
import { createClient } from 'webdav'
|
import { createClient } from 'webdav'
|
||||||
import { getRootPath } from '../utils/davUtils.js'
|
import { getRootPath } from '../utils/davUtils.js'
|
||||||
import { getRequestToken } from '@nextcloud/auth'
|
import { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
|
||||||
|
|
||||||
// init webdav client
|
// init webdav client
|
||||||
const client = createClient(getRootPath(), {
|
const client = createClient(getRootPath())
|
||||||
headers: {
|
|
||||||
// Add this so the server knows it is an request from the browser
|
// set CSRF token header
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
const setHeaders = (token) => {
|
||||||
// Inject user auth
|
client.setHeaders({
|
||||||
requesttoken: getRequestToken() ?? '',
|
// 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
|
export default client
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
import { parseXML, type DAVResult, type FileStat, type ResponseDataDetailed } from 'webdav'
|
import { parseXML, type DAVResult, type FileStat, type ResponseDataDetailed } from 'webdav'
|
||||||
|
|
||||||
// https://github.com/perry-mitchell/webdav-client/issues/339
|
// https://github.com/perry-mitchell/webdav-client/issues/339
|
||||||
import { processResponsePayload } from '../../../../node_modules/webdav/dist/node/response.js'
|
import { processResponsePayload } from 'webdav/dist/node/response.js'
|
||||||
import { prepareFileFromProps } from '../../../../node_modules/webdav/dist/node/tools/dav.js'
|
import { prepareFileFromProps } from 'webdav/dist/node/tools/dav.js'
|
||||||
import client from './DavClient.js'
|
import client from './DavClient.js'
|
||||||
|
|
||||||
export const DEFAULT_LIMIT = 20
|
export const DEFAULT_LIMIT = 20
|
||||||
|
@ -77,10 +77,8 @@ const getDirectoryFiles = function(
|
||||||
// Map all items to a consistent output structure (results)
|
// Map all items to a consistent output structure (results)
|
||||||
return responseItems.map(item => {
|
return responseItems.map(item => {
|
||||||
// Each item should contain a stat object
|
// Each item should contain a stat object
|
||||||
const {
|
const props = item.propstat!.prop!;
|
||||||
propstat: { prop: props },
|
|
||||||
} = item
|
|
||||||
|
|
||||||
return prepareFileFromProps(props, props.id.toString(), isDetailed)
|
return prepareFileFromProps(props, props.id!.toString(), isDetailed)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,21 +19,29 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as webdav from 'webdav'
|
import { createClient } from 'webdav'
|
||||||
import axios from '@nextcloud/axios'
|
|
||||||
import memoize from 'lodash/fp/memoize.js'
|
import memoize from 'lodash/fp/memoize.js'
|
||||||
import { generateRemoteUrl } from '@nextcloud/router'
|
import { generateRemoteUrl } from '@nextcloud/router'
|
||||||
import { getCurrentUser } from '@nextcloud/auth'
|
import { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
|
||||||
|
|
||||||
export const getClient = memoize((service) => {
|
export const getClient = memoize((service) => {
|
||||||
// Add this so the server knows it is an request from the browser
|
// init webdav client
|
||||||
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
|
const remote = generateRemoteUrl(`dav/${service}/${getCurrentUser().uid}`)
|
||||||
|
const client = createClient(remote)
|
||||||
|
|
||||||
// force our axios
|
// set CSRF token header
|
||||||
const patcher = webdav.getPatcher()
|
const setHeaders = (token) => {
|
||||||
patcher.patch('request', axios)
|
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(
|
// refresh headers when request token changes
|
||||||
generateRemoteUrl(`dav/${service}/${getCurrentUser().uid}`)
|
onRequestTokenUpdate(setHeaders)
|
||||||
)
|
setHeaders(getRequestToken())
|
||||||
|
|
||||||
|
return client;
|
||||||
})
|
})
|
||||||
|
|
|
@ -19,22 +19,30 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
import type { RequestOptions, Response } from 'webdav'
|
|
||||||
|
|
||||||
import { createClient, getPatcher } from 'webdav'
|
import { createClient, getPatcher } from 'webdav'
|
||||||
import { generateRemoteUrl } from '@nextcloud/router'
|
import { generateRemoteUrl } from '@nextcloud/router'
|
||||||
import { getCurrentUser, getRequestToken } from '@nextcloud/auth'
|
import { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
|
||||||
import { request } from 'webdav/dist/node/request.js'
|
|
||||||
|
|
||||||
export const rootPath = `/files/${getCurrentUser()?.uid}`
|
export const rootPath = `/files/${getCurrentUser()?.uid}`
|
||||||
export const defaultRootUrl = generateRemoteUrl('dav' + rootPath)
|
export const defaultRootUrl = generateRemoteUrl('dav' + rootPath)
|
||||||
|
|
||||||
export const getClient = (rootUrl = defaultRootUrl) => {
|
export const getClient = (rootUrl = defaultRootUrl) => {
|
||||||
const client = createClient(rootUrl, {
|
const client = createClient(rootUrl)
|
||||||
headers: {
|
|
||||||
requesttoken: getRequestToken() || '',
|
// 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
|
* 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
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
// https://github.com/perry-mitchell/hot-patcher/issues/6
|
// https://github.com/perry-mitchell/hot-patcher/issues/6
|
||||||
patcher.patch('request', (options: RequestOptions): Promise<Response> => {
|
patcher.patch('fetch', (url: string, options: RequestInit): Promise<Response> => {
|
||||||
if (options.headers?.method) {
|
const headers = options.headers as Record<string, string>
|
||||||
options.method = options.headers.method
|
if (headers?.method) {
|
||||||
delete options.headers.method
|
options.method = headers.method
|
||||||
|
delete headers.method
|
||||||
}
|
}
|
||||||
return request(options)
|
return fetch(url, options)
|
||||||
})
|
})
|
||||||
return client
|
|
||||||
|
return client;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,15 +19,28 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createClient } from 'webdav'
|
import { createClient } from 'webdav'
|
||||||
import { generateRemoteUrl } from '@nextcloud/router'
|
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 rootPath = `/trashbin/${getCurrentUser()?.uid}/trash`
|
||||||
export const rootUrl = generateRemoteUrl('dav' + rootPath)
|
export const rootUrl = generateRemoteUrl('dav' + rootPath)
|
||||||
const client = createClient(rootUrl, {
|
const client = createClient(rootUrl)
|
||||||
headers: {
|
|
||||||
requesttoken: getRequestToken(),
|
// 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
|
export default client
|
||||||
|
|
|
@ -21,17 +21,25 @@
|
||||||
|
|
||||||
import { createClient } from 'webdav'
|
import { createClient } from 'webdav'
|
||||||
import { generateRemoteUrl } from '@nextcloud/router'
|
import { generateRemoteUrl } from '@nextcloud/router'
|
||||||
import { getRequestToken } from '@nextcloud/auth'
|
import { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
|
||||||
|
|
||||||
|
// init webdav client
|
||||||
const rootPath = 'dav'
|
const rootPath = 'dav'
|
||||||
|
|
||||||
// init webdav client on default dav endpoint
|
|
||||||
const remote = generateRemoteUrl(rootPath)
|
const remote = generateRemoteUrl(rootPath)
|
||||||
export default createClient(remote, {
|
const client = createClient(remote)
|
||||||
headers: {
|
|
||||||
// Add this so the server knows it is an request from the browser
|
// set CSRF token header
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
const setHeaders = (token) => {
|
||||||
// Inject user auth
|
client.setHeaders({
|
||||||
requesttoken: getRequestToken() ?? '',
|
// 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
|
|
@ -22,12 +22,22 @@
|
||||||
|
|
||||||
import { createClient } from 'webdav'
|
import { createClient } from 'webdav'
|
||||||
import { generateRemoteUrl } from '@nextcloud/router'
|
import { generateRemoteUrl } from '@nextcloud/router'
|
||||||
import { getRequestToken } from '@nextcloud/auth'
|
import { getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
|
||||||
|
|
||||||
|
// init webdav client
|
||||||
const rootUrl = generateRemoteUrl('dav')
|
const rootUrl = generateRemoteUrl('dav')
|
||||||
|
export const davClient = createClient(rootUrl)
|
||||||
|
|
||||||
export const davClient = createClient(rootUrl, {
|
// set CSRF token header
|
||||||
headers: {
|
const setHeaders = (token: string | null) => {
|
||||||
requesttoken: getRequestToken() ?? '',
|
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())
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue