Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dav): Fix DAV functions to make work with them easier #725

Merged
merged 1 commit into from Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 8 additions & 8 deletions __tests__/dav/dav.spec.ts
@@ -1,7 +1,7 @@
import { afterAll, describe, expect, test, vi } from 'vitest'
import { readFile } from 'fs/promises'
import { readFile } from 'node:fs/promises'

import { File, Folder, davDefaultRootUrl, davGetDefaultPropfind, davGetFavoritesReport, davRootPath, getFavoriteNodes } from '../../lib'
import { File, Folder, davRemoteURL, davGetFavoritesReport, davRootPath, getFavoriteNodes } from '../../lib'

vi.mock('@nextcloud/auth')
vi.mock('@nextcloud/router')
Expand All @@ -15,8 +15,8 @@
expect(davRootPath).toBe('/files/test')
})

test('root url is correct', () => {
expect(davDefaultRootUrl).toBe('https://localhost/dav/files/test')
test('remote url is correct', () => {
expect(davRemoteURL).toBe('https://localhost/dav')
})
})

Expand All @@ -26,7 +26,7 @@

// Mock the WebDAV client
const client = {
getDirectoryContents: vi.fn((path: string, options: any) => {

Check warning on line 29 in __tests__/dav/dav.spec.ts

View workflow job for this annotation

GitHub Actions / eslint

Unexpected any. Specify a different type
if (options?.details) {
return {
data: favoritesResponseJSON,
Expand All @@ -39,7 +39,7 @@
const nodes = await getFavoriteNodes(client as never)
// Check client was called correctly
expect(client.getDirectoryContents).toBeCalled()
expect(client.getDirectoryContents.mock.lastCall?.at(0)).toBe('/')
expect(client.getDirectoryContents.mock.lastCall?.at(0)).toBe(`${davRootPath}/`)
expect(client.getDirectoryContents.mock.lastCall?.at(1)?.data).toBe(davGetFavoritesReport())
expect(client.getDirectoryContents.mock.lastCall?.at(1)?.headers?.method).toBe('REPORT')
// Check for correct output
Expand All @@ -55,7 +55,7 @@

// Mock the WebDAV client
const client = {
getDirectoryContents: vi.fn((path: string, options: any) => {

Check warning on line 58 in __tests__/dav/dav.spec.ts

View workflow job for this annotation

GitHub Actions / eslint

Unexpected any. Specify a different type
if (options?.details) {
return {
data: favoritesResponseJSON,
Expand All @@ -68,9 +68,9 @@
const nodes = await getFavoriteNodes(client as never, '/Neuer Ordner')
// Check client was called correctly
expect(client.getDirectoryContents).toBeCalled()
expect(client.getDirectoryContents.mock.lastCall?.at(0)).toBe('/Neuer Ordner')
expect(client.getDirectoryContents.mock.lastCall?.at(1)?.data).toBe(davGetDefaultPropfind())
expect(client.getDirectoryContents.mock.lastCall?.at(1)?.headers?.method).toBe('PROPFIND')
expect(client.getDirectoryContents.mock.lastCall?.at(0)).toBe(`${davRootPath}/Neuer Ordner`)
expect(client.getDirectoryContents.mock.lastCall?.at(1)?.data).toBe(davGetFavoritesReport())
expect(client.getDirectoryContents.mock.lastCall?.at(1)?.headers?.method).toBe('REPORT')
// There are no inner nodes
expect(nodes.length).toBe(0)
})
Expand Down
43 changes: 31 additions & 12 deletions lib/dav/dav.ts
Expand Up @@ -27,7 +27,7 @@ import { File } from '../files/file'
import { Folder } from '../files/folder'
import { NodeData } from '../files/nodeData'
import { davParsePermissions } from './davPermissions'
import { davGetDefaultPropfind, davGetFavoritesReport } from './davProperties'
import { davGetFavoritesReport } from './davProperties'

import { getCurrentUser, getRequestToken } from '@nextcloud/auth'
import { generateRemoteUrl } from '@nextcloud/router'
Expand All @@ -43,15 +43,22 @@ interface ResponseProps extends DAVResultResponseProps {
size: number
}

/**
* The DAV root path for the current user
*/
export const davRootPath = `/files/${getCurrentUser()?.uid}`
export const davDefaultRootUrl = generateRemoteUrl('dav' + davRootPath)

/**
* The DAV remote URL used as base URL for the WebDAV client
*/
export const davRemoteURL = generateRemoteUrl('dav')

/**
* Get a WebDAV client configured to include the Nextcloud request token
*
* @param davURL The DAV root URL
* @param davURL The DAV remote URL
*/
export const davGetClient = function(davURL = davDefaultRootUrl) {
export const davGetClient = function(davURL = davRemoteURL) {
const client = createClient(davURL, {
headers: {
requesttoken: getRequestToken() || '',
Expand Down Expand Up @@ -82,20 +89,32 @@ export const davGetClient = function(davURL = davDefaultRootUrl) {
*
* @param davClient The WebDAV client to use for performing the request
* @param path Base path for the favorites, if unset all favorites are queried
* @param davRoot The root path for the DAV user (defaults to `davRootPath`)
* @example
* ```js
* import { davGetClient, davRootPath, getFavoriteNodes } from '@nextcloud/files'
*
* const client = davGetClient()
* // query favorites for the root
* const favorites = await getFavoriteNodes(client)
* // which is the same as writing:
* const favorites = await getFavoriteNodes(client, '/', davRootPath)
* ```
*/
export const getFavoriteNodes = async (davClient: WebDAVClient, path = '/') => {
const contentsResponse = await davClient.getDirectoryContents(path, {
export const getFavoriteNodes = async (davClient: WebDAVClient, path = '/', davRoot = davRootPath) => {
const contentsResponse = await davClient.getDirectoryContents(`${davRoot}${path}`, {
details: true,
// Only filter favorites if we're at the root
data: path === '/' ? davGetFavoritesReport() : davGetDefaultPropfind(),
data: davGetFavoritesReport(),
headers: {
// Patched in WebdavClient.ts
method: path === '/' ? 'REPORT' : 'PROPFIND',
// see davGetClient for patched webdav client
method: 'REPORT',
},
includeSelf: true,
}) as ResponseDataDetailed<FileStat[]>

return contentsResponse.data.filter(node => node.filename !== path).map((result) => davResultToNode(result))
return contentsResponse.data
.filter(node => node.filename !== path) // exclude current dir
.map((result) => davResultToNode(result, davRoot))
}

/**
Expand All @@ -114,7 +133,7 @@ export const davResultToNode = function(node: FileStat, davRoot = davRootPath):
source: generateRemoteUrl(`dav${davRoot}${node.filename}`),
mtime: new Date(Date.parse(node.lastmod)),
mime: node.mime as string,
size: (props?.size as number) || 0,
size: props?.size || Number.parseInt(props.getcontentlength || '0'),
permissions,
owner,
root: davRoot,
Expand Down