diff --git a/packages/@uppy/companion/package.json b/packages/@uppy/companion/package.json index 4ca27d30ad..6453ab4b46 100644 --- a/packages/@uppy/companion/package.json +++ b/packages/@uppy/companion/package.json @@ -65,6 +65,7 @@ "supports-color": "8.x", "tus-js-client": "^4.1.0", "validator": "^13.0.0", + "webdav": "5.7.1", "ws": "8.17.1" }, "devDependencies": { diff --git a/packages/@uppy/companion/src/server/controllers/get.js b/packages/@uppy/companion/src/server/controllers/get.js index 1ba7f916ae..6364399967 100644 --- a/packages/@uppy/companion/src/server/controllers/get.js +++ b/packages/@uppy/companion/src/server/controllers/get.js @@ -8,7 +8,7 @@ async function get (req, res) { const { provider } = req.companion async function getSize () { - return provider.size({ id, token: accessToken, query: req.query }) + return provider.size({ id, token: accessToken, providerUserSession, query: req.query }) } const download = () => provider.download({ id, token: accessToken, providerUserSession, query: req.query }) diff --git a/packages/@uppy/companion/src/server/provider/index.js b/packages/@uppy/companion/src/server/provider/index.js index 52c707dac0..c378d80ce2 100644 --- a/packages/@uppy/companion/src/server/provider/index.js +++ b/packages/@uppy/companion/src/server/provider/index.js @@ -9,6 +9,7 @@ const instagram = require('./instagram/graph') const facebook = require('./facebook') const onedrive = require('./onedrive') const unsplash = require('./unsplash') +const webdav = require('./webdav') const zoom = require('./zoom') const { getURLBuilder } = require('../helpers/utils') const logger = require('../logger') @@ -68,7 +69,7 @@ module.exports.getProviderMiddleware = (providers, grantConfig) => { * @returns {Record} */ module.exports.getDefaultProviders = () => { - const providers = { dropbox, box, drive, googlephotos, facebook, onedrive, zoom, instagram, unsplash } + const providers = { dropbox, box, drive, googlephotos, facebook, onedrive, zoom, instagram, unsplash, webdav } return providers } diff --git a/packages/@uppy/companion/src/server/provider/webdav/common.js b/packages/@uppy/companion/src/server/provider/webdav/common.js new file mode 100644 index 0000000000..316f449f91 --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/webdav/common.js @@ -0,0 +1,125 @@ +const Provider = require('../Provider') +const logger = require('../../logger') +const { getProtectedHttpAgent, validateURL } = require('../../helpers/request') +const { ProviderApiError, ProviderAuthError } = require('../error') + +/** + * WebdavProvider base class provides implementations that could be shared by simple and oauth providers + */ +class WebdavProvider extends Provider { + async getClientHelper ({ url, ...options }) { + const { allowLocalUrls } = this + if (!validateURL(url, allowLocalUrls)) { + throw new Error('invalid webdav url') + } + const { protocol } = new URL(url) + const HttpAgentClass = getProtectedHttpAgent({ protocol, allowLocalIPs: !allowLocalUrls }) + + const { createClient } = await import('webdav') + return createClient(url, { + ...options, + [`${protocol}Agent`] : new HttpAgentClass(), + }) + } + + async getClient ({ username, token, providerUserSession }) { // eslint-disable-line no-unused-vars,class-methods-use-this + logger.error('call to getUsername is not implemented', 'provider.webdav.getUsername.error') + throw new Error('call to getUsername is not implemented') + // todo: use @returns to specify the return type + return this.getClientHelper() // eslint-disable-line + } + + async getUsername ({ token, providerUserSession }) { // eslint-disable-line no-unused-vars,class-methods-use-this + logger.error('call to getUsername is not implemented', 'provider.webdav.getUsername.error') + throw new Error('call to getUsername is not implemented') + } + + /** @protected */ + // eslint-disable-next-line class-methods-use-this + isAuthenticated () { + throw new Error('Not implemented') + } + + async list ({ directory, token, providerUserSession }) { + return this.withErrorHandling('provider.webdav.list.error', async () => { + // @ts-ignore + if (!this.isAuthenticated({ providerUserSession })) { + throw new ProviderAuthError() + } + + const username = await this.getUsername({ token, providerUserSession }) + const data = { username, items: [] } + const client = await this.getClient({ username, token, providerUserSession }) + + /** @type {any} */ + const dir = await client.getDirectoryContents(directory || '/') + + dir.forEach(item => { + const isFolder = item.type === 'directory' + const requestPath = encodeURIComponent(`${directory || ''}/${item.basename}`) + data.items.push({ + isFolder, + id: requestPath, + name: item.basename, + requestPath, // TODO FIXME + modifiedDate: item.lastmod, // TODO FIXME: convert 'Tue, 04 Jul 2023 13:09:47 GMT' to ISO 8601 + ...(!isFolder && { + mimeType: item.mime, + size: item.size, + thumbnail: null, + + }), + }) + }) + + return data + }) + } + + async download ({ id, token, providerUserSession }) { + return this.withErrorHandling('provider.webdav.download.error', async () => { + // maybe we can avoid this by putting the username in front of the request path/id + const username = await this.getUsername({ token, providerUserSession }) + const client = await this.getClient({ username, token, providerUserSession }) + const stream = client.createReadStream(`/${id}`) + return { stream } + }) + } + + // eslint-disable-next-line + async thumbnail ({ id, providerUserSession }) { + // not implementing this because a public thumbnail from webdav will be used instead + logger.error('call to thumbnail is not implemented', 'provider.webdav.thumbnail.error') + throw new Error('call to thumbnail is not implemented') + } + + // todo fixme implement + // eslint-disable-next-line + async size ({ id, token, providerUserSession }) { + return this.withErrorHandling('provider.webdav.size.error', async () => { + const username = await this.getUsername({ token, providerUserSession }) + const client = await this.getClient({ username, token, providerUserSession }) + + /** @type {any} */ + const stat = await client.stat(id) + return stat.size + }) + } + + // eslint-disable-next-line class-methods-use-this + async withErrorHandling (tag, fn) { + try { + return await fn() + } catch (err) { + let err2 = err + if (err.status === 401) err2 = new ProviderAuthError() + if (err.response) { + err2 = new ProviderApiError('WebDAV API error', err.status) // todo improve (read err?.response?.body readable stream and parse response) + } + logger.error(err2, tag) + throw err2 + } + } +} + +module.exports = WebdavProvider diff --git a/packages/@uppy/companion/src/server/provider/webdav/index.js b/packages/@uppy/companion/src/server/provider/webdav/index.js new file mode 100644 index 0000000000..90ee83e53f --- /dev/null +++ b/packages/@uppy/companion/src/server/provider/webdav/index.js @@ -0,0 +1,80 @@ + +const { validateURL } = require('../../helpers/request') +const WebdavProvider = require('./common') +const { ProviderUserError } = require('../error') +const logger = require('../../logger') + +const defaultDirectory = '/' + +/** + * Adapter for WebDAV servers that support simple auth (non-OAuth). + */ +class WebdavSimpleAuthProvider extends WebdavProvider { + static get hasSimpleAuth () { + return true + } + + async getUsername () { // eslint-disable-line class-methods-use-this + return null + } + + // eslint-disable-next-line class-methods-use-this + isAuthenticated ({ providerUserSession }) { + return providerUserSession.webdavUrl != null + } + + async getClient ({ providerUserSession }) { + const webdavUrl = providerUserSession?.webdavUrl + const { allowLocalUrls } = this + if (!validateURL(webdavUrl, allowLocalUrls)) { + throw new Error('invalid public link url') + } + + const { AuthType } = await import('webdav') // eslint-disable-line import/no-unresolved + + // Is this an ownCloud or Nextcloud public link URL? e.g. https://example.com/s/kFy9Lek5sm928xP + // they have specific urls that we can identify + // todo not sure if this is the right way to support nextcloud and other webdavs + if (/\/s\/([^/]+)/.test(webdavUrl)) { + const [baseURL, publicLinkToken] = webdavUrl.split('/s/') + + return this.getClientHelper({ + url: `${baseURL.replace('/index.php', '')}/public.php/webdav/`, + authType: AuthType.Password, + username: publicLinkToken, + password: 'null', + }) + } + + // normal public WebDAV urls + return this.getClientHelper({ + url: webdavUrl, + authType: AuthType.None, + }) + } + + async logout () { // eslint-disable-line class-methods-use-this + return { revoked: true } + } + + async simpleAuth ({ requestBody }) { + try { + const providerUserSession = { webdavUrl: requestBody.form.webdavUrl } + + const client = await this.getClient({ providerUserSession }) + // call the list operation as a way to validate the url + await client.getDirectoryContents(defaultDirectory) + + return providerUserSession + } catch (err) { + logger.error(err, 'provider.webdav.error') + if (['ECONNREFUSED', 'ENOTFOUND'].includes(err.code)) { + throw new ProviderUserError({ message: 'Cannot connect to server' }) + } + // todo report back to the user what actually went wrong + throw err + } + } +} + +module.exports = WebdavSimpleAuthProvider diff --git a/packages/@uppy/webdav/package.json b/packages/@uppy/webdav/package.json new file mode 100644 index 0000000000..d753114830 --- /dev/null +++ b/packages/@uppy/webdav/package.json @@ -0,0 +1,35 @@ +{ + "name": "@uppy/webdav", + "description": "Import files from WebDAV into Uppy.", + "version": "3.1.1", + "license": "MIT", + "main": "lib/index.js", + "types": "types/index.d.ts", + "type": "module", + "keywords": [ + "file uploader", + "uppy", + "uppy-plugin", + "instagram", + "provider", + "photos", + "videos" + ], + "homepage": "https://uppy.io", + "bugs": { + "url": "https://github.com/transloadit/uppy/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/transloadit/uppy.git" + }, + "dependencies": { + "@uppy/companion-client": "workspace:^", + "@uppy/provider-views": "workspace:^", + "@uppy/utils": "workspace:^", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "workspace:^" + } +} diff --git a/packages/@uppy/webdav/src/Webdav.tsx b/packages/@uppy/webdav/src/Webdav.tsx new file mode 100644 index 0000000000..a23e9fde6e --- /dev/null +++ b/packages/@uppy/webdav/src/Webdav.tsx @@ -0,0 +1,117 @@ +import { h } from 'preact' +import { useCallback, useState } from 'preact/hooks' + +import { UIPlugin } from '@uppy/core' +import { Provider, tokenStorage } from '@uppy/companion-client' +import { ProviderViews } from '@uppy/provider-views' + +import packageJson from '../package.json' +import locale from './locale.ts' + +class WebdavSimpleAuthProvider extends Provider { + async login({ authFormData, uppyVersions, signal }) { + return this.loginSimpleAuth({ uppyVersions, authFormData, signal }) + } + + async logout() { + this.removeAuthToken() + return { ok: true, revoked: true } + } +} + +const AuthForm = ({ loading, i18n, onAuth }) => { + const [webdavUrl, setWebdavUrl] = useState('') + + const onSubmit = useCallback( + (e) => { + e.preventDefault() + onAuth({ webdavUrl: webdavUrl.trim() }) + }, + [onAuth, webdavUrl], + ) + + return ( +
+ + + {i18n('publicLinkURLDescription')} + + + +
+ ) +} + +export default class Webdav extends UIPlugin { + static VERSION = packageJson.version + + constructor(uppy, opts) { + super(uppy, opts) + this.id = this.opts.id || 'webdav' + this.type = 'acquirer' + this.storage = this.opts.storage || tokenStorage + + this.defaultLocale = locale + + console.log(locale) + this.i18nInit() + + this.title = this.i18n('pluginNameWebdav') + + this.provider = new WebdavSimpleAuthProvider(uppy, { + companionUrl: this.opts.companionUrl, + companionHeaders: this.opts.companionHeaders, + companionKeysParams: this.opts.companionKeysParams, + companionCookiesRule: this.opts.companionCookiesRule, + provider: 'webdav', + pluginId: this.id, + supportsRefreshToken: false, + }) + + this.onFirstRender = this.onFirstRender.bind(this) + this.render = this.render.bind(this) + } + + install() { + this.view = new ProviderViews(this, { + provider: this.provider, + viewType: 'list', + showTitles: true, + showFilter: true, + showBreadcrumbs: true, + renderAuthForm: ({ i18n, loading, onAuth }) => ( + + ), + }) + + const { target } = this.opts + if (target) { + this.mount(target, this) + } + } + + uninstall() { + this.view.tearDown() + this.unmount() + } + + onFirstRender() { + return this.view.getFolder() + } + + render(state) { + return this.view.render(state) + } +} diff --git a/packages/@uppy/webdav/src/index.ts b/packages/@uppy/webdav/src/index.ts new file mode 100644 index 0000000000..b643568134 --- /dev/null +++ b/packages/@uppy/webdav/src/index.ts @@ -0,0 +1,2 @@ +export { default } from './Webdav.tsx' +export type { WebcamOptions } from './Webcam.tsx' diff --git a/packages/@uppy/webdav/src/locale.ts b/packages/@uppy/webdav/src/locale.ts new file mode 100644 index 0000000000..414505937a --- /dev/null +++ b/packages/@uppy/webdav/src/locale.ts @@ -0,0 +1,8 @@ +export default { + strings: { + pluginNameWebdav: 'WebDAV', + publicLinkURLLabel: 'URL', + publicLinkURLDescription: + 'WebDAV url or an ownCloud or Nextcloud public link', + }, +} diff --git a/packages/uppy/package.json b/packages/uppy/package.json index db2688a9be..e132b6b336 100644 --- a/packages/uppy/package.json +++ b/packages/uppy/package.json @@ -65,6 +65,7 @@ "@uppy/unsplash": "workspace:^", "@uppy/url": "workspace:^", "@uppy/webcam": "workspace:^", + "@uppy/webdav": "workspace:^", "@uppy/xhr-upload": "workspace:^", "@uppy/zoom": "workspace:^" } diff --git a/private/dev/Dashboard.js b/private/dev/Dashboard.js index f71abf5e09..ed3486ebf5 100644 --- a/private/dev/Dashboard.js +++ b/private/dev/Dashboard.js @@ -15,6 +15,7 @@ import DropTarget from '@uppy/drop-target' import Audio from '@uppy/audio' import Compressor from '@uppy/compressor' import GoogleDrive from '@uppy/google-drive' +import Webdav from '@uppy/webdav' import english from '@uppy/locales/lib/en_US.js' /* eslint-enable import/no-extraneous-dependencies */ @@ -145,6 +146,11 @@ export default () => { showVideoSourceDropdown: true, showRecordingLength: true, }) + .use(Webdav, { + target: Dashboard, + companionUrl: COMPANION_URL, + companionAllowedHosts + }) .use(Audio, { target: Dashboard, showRecordingLength: true, diff --git a/yarn.lock b/yarn.lock index 426223c54b..e6b51cae24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3100,6 +3100,18 @@ __metadata: languageName: node linkType: hard +"@buttercup/fetch@npm:^0.2.1": + version: 0.2.1 + resolution: "@buttercup/fetch@npm:0.2.1" + dependencies: + node-fetch: "npm:^3.3.0" + dependenciesMeta: + node-fetch: + optional: true + checksum: 10/ad2fc2ce964409a44238cca94a93ad3817666c477fd1c1ace914a3c589c638522747545bf53f3a684c10a2edf957134dc2d3fa7effe5a773d1bea2c2bee9dd2c + languageName: node + linkType: hard + "@cnakazawa/watch@npm:^1.0.3": version: 1.0.4 resolution: "@cnakazawa/watch@npm:1.0.4" @@ -8729,6 +8741,7 @@ __metadata: tus-js-client: "npm:^4.1.0" typescript: "npm:~5.4" validator: "npm:^13.0.0" + webdav: "npm:5.7.1" ws: "npm:8.17.1" bin: companion: ./bin/companion @@ -9247,6 +9260,19 @@ __metadata: languageName: unknown linkType: soft +"@uppy/webdav@workspace:^, @uppy/webdav@workspace:packages/@uppy/webdav": + version: 0.0.0-use.local + resolution: "@uppy/webdav@workspace:packages/@uppy/webdav" + dependencies: + "@uppy/companion-client": "workspace:^" + "@uppy/provider-views": "workspace:^" + "@uppy/utils": "workspace:^" + preact: "npm:^10.5.13" + peerDependencies: + "@uppy/core": "workspace:^" + languageName: unknown + linkType: soft + "@uppy/xhr-upload@workspace:*, @uppy/xhr-upload@workspace:^, @uppy/xhr-upload@workspace:packages/@uppy/xhr-upload": version: 0.0.0-use.local resolution: "@uppy/xhr-upload@workspace:packages/@uppy/xhr-upload" @@ -10789,6 +10815,13 @@ __metadata: languageName: node linkType: hard +"base-64@npm:^1.0.0": + version: 1.0.0 + resolution: "base-64@npm:1.0.0" + checksum: 10/d10b64a1fc9b2c5a5f39f1ce1e6c9d1c5b249222bbfa3a0604c592d90623caf74419983feadd8a170f27dc0c3389704f72faafa3e645aeb56bfc030c93ff074a + languageName: node + linkType: hard + "base-x@npm:^3.0.8": version: 3.0.9 resolution: "base-x@npm:3.0.9" @@ -11191,6 +11224,13 @@ __metadata: languageName: node linkType: hard +"byte-length@npm:^1.0.2": + version: 1.0.2 + resolution: "byte-length@npm:1.0.2" + checksum: 10/69e2b00a14a81f675ea9946135c42ee1a1d9f689d5ba1327eb6700fcde2ccacbd09b42f7e514de1d2b763960251d8c790b3d7304a5a1a27b1457e34c129be8c7 + languageName: node + linkType: hard + "bytes@npm:3.0.0": version: 3.0.0 resolution: "bytes@npm:3.0.0" @@ -11526,6 +11566,13 @@ __metadata: languageName: node linkType: hard +"charenc@npm:0.0.2": + version: 0.0.2 + resolution: "charenc@npm:0.0.2" + checksum: 10/81dcadbe57e861d527faf6dd3855dc857395a1c4d6781f4847288ab23cffb7b3ee80d57c15bba7252ffe3e5e8019db767757ee7975663ad2ca0939bb8fcaf2e5 + languageName: node + linkType: hard + "check-error@npm:^1.0.3": version: 1.0.3 resolution: "check-error@npm:1.0.3" @@ -12481,6 +12528,13 @@ __metadata: languageName: node linkType: hard +"crypt@npm:0.0.2": + version: 0.0.2 + resolution: "crypt@npm:0.0.2" + checksum: 10/2c72768de3d28278c7c9ffd81a298b26f87ecdfe94415084f339e6632f089b43fe039f2c93f612bcb5ffe447238373d93b2e8c90894cba6cfb0ac7a74616f8b9 + languageName: node + linkType: hard + "css-declaration-sorter@npm:^7.2.0": version: 7.2.0 resolution: "css-declaration-sorter@npm:7.2.0" @@ -12808,6 +12862,13 @@ __metadata: languageName: node linkType: hard +"data-uri-to-buffer@npm:^4.0.0": + version: 4.0.1 + resolution: "data-uri-to-buffer@npm:4.0.1" + checksum: 10/0d0790b67ffec5302f204c2ccca4494f70b4e2d940fea3d36b09f0bb2b8539c2e86690429eb1f1dc4bcc9e4df0644193073e63d9ee48ac9fce79ec1506e4aa4c + languageName: node + linkType: hard + "data-urls@npm:^5.0.0": version: 5.0.0 resolution: "data-urls@npm:5.0.0" @@ -13739,6 +13800,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:^5.0.0": + version: 5.0.0 + resolution: "entities@npm:5.0.0" + checksum: 10/d7d1b855abee681e7570c1357c94986662c890890c30601ddaf59b7b2b63fcc225118e784ffa96f6bea39bfa675252831e32af49b1f7ebe5ceabf89d820f2beb + languageName: node + linkType: hard + "env-paths@npm:^2.2.0, env-paths@npm:^2.2.1": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -15434,6 +15502,17 @@ __metadata: languageName: node linkType: hard +"fast-xml-parser@npm:^4.4.1": + version: 4.5.0 + resolution: "fast-xml-parser@npm:4.5.0" + dependencies: + strnum: "npm:^1.0.5" + bin: + fxparser: src/cli/cli.js + checksum: 10/dc9571c10e7b57b5be54bcd2d92f50c446eb42ea5df347d253e94dd14eb99b5300a6d172e840f151e0721933ca2406165a8d9b316a6d777bf0596dc4fe1df756 + languageName: node + linkType: hard + "fastest-levenshtein@npm:^1.0.16": version: 1.0.16 resolution: "fastest-levenshtein@npm:1.0.16" @@ -15532,6 +15611,16 @@ __metadata: languageName: node linkType: hard +"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4": + version: 3.2.0 + resolution: "fetch-blob@npm:3.2.0" + dependencies: + node-domexception: "npm:^1.0.0" + web-streams-polyfill: "npm:^3.0.3" + checksum: 10/5264ecceb5fdc19eb51d1d0359921f12730941e333019e673e71eb73921146dceabcb0b8f534582be4497312d656508a439ad0f5edeec2b29ab2e10c72a1f86b + languageName: node + linkType: hard + "figures@npm:^3.2.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -15859,6 +15948,15 @@ __metadata: languageName: node linkType: hard +"formdata-polyfill@npm:^4.0.10": + version: 4.0.10 + resolution: "formdata-polyfill@npm:4.0.10" + dependencies: + fetch-blob: "npm:^3.1.2" + checksum: 10/9b5001d2edef3c9449ac3f48bd4f8cc92e7d0f2e7c1a5c8ba555ad4e77535cc5cf621fabe49e97f304067037282dd9093b9160a3cb533e46420b446c4e6bc06f + languageName: node + linkType: hard + "formidable@npm:^2.1.2": version: 2.1.2 resolution: "formidable@npm:2.1.2" @@ -16729,6 +16827,13 @@ __metadata: languageName: node linkType: hard +"hot-patcher@npm:^2.0.1": + version: 2.0.1 + resolution: "hot-patcher@npm:2.0.1" + checksum: 10/c207007dd55609527bcb26450606c714c313ac52af466746d25916f722da2c48fd1257871c07bd07af5ee586f2c1bf8ab59919db66dcea4a2c82b7c51c9a1317 + languageName: node + linkType: hard + "hpack.js@npm:^2.1.6": version: 2.1.6 resolution: "hpack.js@npm:2.1.6" @@ -17488,7 +17593,7 @@ __metadata: languageName: node linkType: hard -"is-buffer@npm:^1.1.5": +"is-buffer@npm:^1.1.5, is-buffer@npm:~1.1.6": version: 1.1.6 resolution: "is-buffer@npm:1.1.6" checksum: 10/f63da109e74bbe8947036ed529d43e4ae0c5fcd0909921dce4917ad3ea212c6a87c29f525ba1d17c0858c18331cf1046d4fc69ef59ed26896b25c8288a627133 @@ -19404,6 +19509,13 @@ __metadata: languageName: node linkType: hard +"layerr@npm:^3.0.0": + version: 3.0.0 + resolution: "layerr@npm:3.0.0" + checksum: 10/5b9518795ef5d447f2b4c66ebab223b0a4fb37505ba27013920f71691726211298e630750d5fa8b03ddb5ce191d24e26d49fa40e0042193ecd680f15d89311f9 + languageName: node + linkType: hard + "lazy-ass@npm:1.6.0, lazy-ass@npm:^1.6.0": version: 1.6.0 resolution: "lazy-ass@npm:1.6.0" @@ -20437,6 +20549,17 @@ __metadata: languageName: node linkType: hard +"md5@npm:^2.3.0": + version: 2.3.0 + resolution: "md5@npm:2.3.0" + dependencies: + charenc: "npm:0.0.2" + crypt: "npm:0.0.2" + is-buffer: "npm:~1.1.6" + checksum: 10/88dce9fb8df1a084c2385726dcc18c7f54e0b64c261b5def7cdfe4928c4ee1cd68695c34108b4fab7ecceb05838c938aa411c6143df9fdc0026c4ddb4e4e72fa + languageName: node + linkType: hard + "mdast-comment-marker@npm:^2.0.0": version: 2.1.2 resolution: "mdast-comment-marker@npm:2.1.2" @@ -21858,6 +21981,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^9.0.5": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10/dd6a8927b063aca6d910b119e1f2df6d2ce7d36eab91de83167dd136bb85e1ebff97b0d3de1cb08bd1f7e018ca170b4962479fefab5b2a69e2ae12cb2edc8348 + languageName: node + linkType: hard + "minimatch@npm:~3.0.2": version: 3.0.8 resolution: "minimatch@npm:3.0.8" @@ -22282,6 +22414,13 @@ __metadata: languageName: node linkType: hard +"nested-property@npm:^4.0.0": + version: 4.0.0 + resolution: "nested-property@npm:4.0.0" + checksum: 10/5653a67d68e19ed045d571b44f1a84ee07f8fd03f314e5876783d17e600d8799c51ff3f6e93892427ab011b81f885300126f231f2d6c7bb192234e6d97bbe245 + languageName: node + linkType: hard + "ng-packagr@npm:^18.0.0": version: 18.0.0 resolution: "ng-packagr@npm:18.0.0" @@ -22450,6 +22589,13 @@ __metadata: languageName: node linkType: hard +"node-domexception@npm:^1.0.0": + version: 1.0.0 + resolution: "node-domexception@npm:1.0.0" + checksum: 10/e332522f242348c511640c25a6fc7da4f30e09e580c70c6b13cb0be83c78c3e71c8d4665af2527e869fc96848924a4316ae7ec9014c091e2156f41739d4fa233 + languageName: node + linkType: hard + "node-fetch@npm:^1.0.1": version: 1.7.3 resolution: "node-fetch@npm:1.7.3" @@ -22474,6 +22620,17 @@ __metadata: languageName: node linkType: hard +"node-fetch@npm:^3.3.0, node-fetch@npm:^3.3.2": + version: 3.3.2 + resolution: "node-fetch@npm:3.3.2" + dependencies: + data-uri-to-buffer: "npm:^4.0.0" + fetch-blob: "npm:^3.1.4" + formdata-polyfill: "npm:^4.0.10" + checksum: 10/24207ca8c81231c7c59151840e3fded461d67a31cf3e3b3968e12201a42f89ce4a0b5fb7079b1fa0a4655957b1ca9257553200f03a9f668b45ebad265ca5593d + languageName: node + linkType: hard + "node-forge@npm:^1": version: 1.3.1 resolution: "node-forge@npm:1.3.1" @@ -23766,6 +23923,13 @@ __metadata: languageName: node linkType: hard +"path-posix@npm:^1.0.0": + version: 1.0.0 + resolution: "path-posix@npm:1.0.0" + checksum: 10/b4eae5cd4b7c943719c2f8679c53d02988bf1701583065cc5b301bb671e6ec13d6e4257257fe92a5c7b34c35e215b322a8976ce89d29dcf8801c0ee2cc75ca18 + languageName: node + linkType: hard + "path-scurry@npm:^1.11.1": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" @@ -29662,6 +29826,7 @@ __metadata: "@uppy/unsplash": "workspace:^" "@uppy/url": "workspace:^" "@uppy/webcam": "workspace:^" + "@uppy/webdav": "workspace:^" "@uppy/xhr-upload": "workspace:^" "@uppy/zoom": "workspace:^" languageName: unknown @@ -29683,7 +29848,14 @@ __metadata: languageName: node linkType: hard -"url-parse@npm:^1.4.4, url-parse@npm:^1.5.3, url-parse@npm:^1.5.7": +"url-join@npm:^5.0.0": + version: 5.0.0 + resolution: "url-join@npm:5.0.0" + checksum: 10/5921384a8ad4395b49ce4b50aa26efbc429cebe0bc8b3660ad693dd12fd859747b5369be0443e60e53a7850b2bc9d7d0687bcb94386662b40e743596bbf38101 + languageName: node + linkType: hard + +"url-parse@npm:^1.4.4, url-parse@npm:^1.5.10, url-parse@npm:^1.5.3, url-parse@npm:^1.5.7": version: 1.5.10 resolution: "url-parse@npm:1.5.10" dependencies: @@ -30250,6 +30422,35 @@ __metadata: languageName: node linkType: hard +"web-streams-polyfill@npm:^3.0.3": + version: 3.3.3 + resolution: "web-streams-polyfill@npm:3.3.3" + checksum: 10/8e7e13501b3834094a50abe7c0b6456155a55d7571312b89570012ef47ec2a46d766934768c50aabad10a9c30dd764a407623e8bfcc74fcb58495c29130edea9 + languageName: node + linkType: hard + +"webdav@npm:5.7.1": + version: 5.7.1 + resolution: "webdav@npm:5.7.1" + dependencies: + "@buttercup/fetch": "npm:^0.2.1" + base-64: "npm:^1.0.0" + byte-length: "npm:^1.0.2" + entities: "npm:^5.0.0" + fast-xml-parser: "npm:^4.4.1" + hot-patcher: "npm:^2.0.1" + layerr: "npm:^3.0.0" + md5: "npm:^2.3.0" + minimatch: "npm:^9.0.5" + nested-property: "npm:^4.0.0" + node-fetch: "npm:^3.3.2" + path-posix: "npm:^1.0.0" + url-join: "npm:^5.0.0" + url-parse: "npm:^1.5.10" + checksum: 10/3b22e32b430d4815a52c5b51d8c2b7ce9b9ff6b03fd32c66ee73d208bd5142a9a15fab18cde674531a37cf8cf4bef2ca0f0d7ca613b4f2d7141f9a6be7c0c135 + languageName: node + linkType: hard + "webidl-conversions@npm:^3.0.0": version: 3.0.1 resolution: "webidl-conversions@npm:3.0.1"