Skip to content

Commit

Permalink
Merge pull request #1225 from nextcloud-libraries/feat/public-upload
Browse files Browse the repository at this point in the history
  • Loading branch information
skjnldsv authored Jun 4, 2024
2 parents c2d5ea7 + c72f783 commit 7dba794
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 4 deletions.
49 changes: 49 additions & 0 deletions __tests__/utils/uploader.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { beforeEach, describe, expect, test, vi } from 'vitest'
import { Uploader } from '../../lib/uploader.js'

import type { NextcloudUser } from '@nextcloud/auth'

const initialState = vi.hoisted(() => ({ loadState: vi.fn() }))
const auth = vi.hoisted(() => ({ getCurrentUser: vi.fn<never, NextcloudUser | null>(() => null) }))
vi.mock('@nextcloud/initial-state', () => initialState)
vi.mock('@nextcloud/auth', () => auth)

describe('uploader', () => {
beforeEach(() => {
vi.resetAllMocks()
const node = document.getElementById('sharingToken')
if (node) {
document.body.removeChild(node)
}
})

test('constructor sets default target folder for user', async () => {
auth.getCurrentUser.mockImplementationOnce(() => ({ uid: 'my-user', displayName: 'User', isAdmin: false }))
const uploader = new Uploader()
expect(uploader.destination.source).match(/\/remote\.php\/dav\/files\/my-user\/?$/)
})

test('constructor sets default target folder for public share', async () => {
initialState.loadState.mockImplementationOnce((app, key) => app === 'files_sharing' && key === 'sharingToken' ? 'token-123' : null)
const uploader = new Uploader(true)
expect(uploader.destination.source).match(/\/public\.php\/dav\/files\/token-123\/?$/)
})

test('constructor sets default target folder for legacy public share', async () => {
const input = document.createElement('input')
input.id = 'sharingToken'
input.value = 'legacy-token'
document.body.appendChild(input)
const uploader = new Uploader(true)
expect(uploader.destination.source).match(/\/public\.php\/dav\/files\/legacy-token\/?$/)
})

test('fails if no sharingToken on public share', async () => {
expect(() => new Uploader(true)).toThrow(/No sharing token found/)
})

test('fails if not logged in and not on public share', async () => {
expect(() => new Uploader()).toThrow(/User is not logged in/)
expect(initialState.loadState).not.toBeCalled()
})
})
24 changes: 20 additions & 4 deletions lib/uploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { WebDAVClient } from 'webdav'

import { getCurrentUser } from '@nextcloud/auth'
import { Folder, Permission, davGetClient } from '@nextcloud/files'
import { loadState } from '@nextcloud/initial-state'
import { encodePath } from '@nextcloud/paths'
import { generateRemoteUrl } from '@nextcloud/router'
import { normalize } from 'path'
Expand Down Expand Up @@ -53,11 +54,26 @@ export class Uploader {
this._isPublic = isPublic

if (!destinationFolder) {
const owner = getCurrentUser()?.uid
const source = generateRemoteUrl(`dav/files/${owner}`)
if (!owner) {
throw new Error('User is not logged in')
let owner: string
let source: string

if (isPublic) {
const sharingToken = loadState<string | null>('files_sharing', 'sharingToken', null) ?? document.querySelector<HTMLInputElement>('input#sharingToken')?.value
if (!sharingToken) {
logger.error('No sharing token found for public shares, please specify the destination folder manually.')
throw new Error('No sharing token found.')
}
owner = sharingToken
source = generateRemoteUrl(`dav/files/${sharingToken}`).replace('remote.php', 'public.php')
} else {
const user = getCurrentUser()?.uid
if (!user) {
throw new Error('User is not logged in')
}
owner = user
source = generateRemoteUrl(`dav/files/${owner}`)
}

destinationFolder = new Folder({
id: 0,
owner,
Expand Down
5 changes: 5 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export default async (env) => {
exclude: ['lib/utils/l10n.ts'],
reporter: ['lcov', 'text'],
},
server: {
deps: {
inline: ['@nextcloud/files'],
},
},
} as UserConfig
return cfg
}

0 comments on commit 7dba794

Please sign in to comment.