From 06ddd99cd1bd367374bb97c5784c557b7ac416fb Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Mon, 14 Jul 2025 12:20:08 +0200 Subject: [PATCH] @uppy/companion: fix (breaking) todo comments (#5802) --- e2e/cypress/fixtures/DeepFrozenStore.mjs | 1 - .../server/CustomProvider.cjs | 2 - examples/xhr-bundle/server.cjs | 1 - .../src/getAllowedHosts.test.ts | 9 +- .../companion-client/src/getAllowedHosts.ts | 3 +- .../@uppy/companion/src/server/Uploader.js | 3 - .../companion/src/server/controllers/get.js | 15 +-- .../companion/src/server/controllers/list.js | 3 - .../src/server/controllers/logout.js | 2 - .../src/server/controllers/thumbnail.js | 2 - .../companion/src/server/helpers/request.js | 2 - .../companion/src/server/helpers/utils.js | 108 ++++++------------ .../companion/src/server/provider/Provider.js | 1 - .../src/server/provider/box/index.js | 17 ++- .../src/server/provider/credentials.js | 2 - .../src/server/provider/dropbox/index.js | 10 +- .../src/server/provider/facebook/index.js | 10 +- .../src/server/provider/google/drive/index.js | 6 +- .../src/server/provider/google/index.js | 2 +- .../server/provider/instagram/graph/index.js | 8 +- .../src/server/provider/onedrive/index.js | 12 +- .../src/server/provider/unsplash/index.js | 7 +- .../src/server/provider/webdav/index.js | 3 +- .../src/server/provider/zoom/index.js | 18 ++- .../test/__tests__/deauthorization.js | 17 ++- packages/@uppy/webcam/src/CameraScreen.tsx | 3 - private/js2ts/index.mjs | 7 +- 27 files changed, 112 insertions(+), 162 deletions(-) diff --git a/e2e/cypress/fixtures/DeepFrozenStore.mjs b/e2e/cypress/fixtures/DeepFrozenStore.mjs index 3a6bbee56..065c33177 100644 --- a/e2e/cypress/fixtures/DeepFrozenStore.mjs +++ b/e2e/cypress/fixtures/DeepFrozenStore.mjs @@ -1,4 +1,3 @@ -// eslint-disable-next-line import/no-extraneous-dependencies import deepFreeze from 'deep-freeze' /* eslint-disable no-underscore-dangle */ diff --git a/examples/companion-custom-provider/server/CustomProvider.cjs b/examples/companion-custom-provider/server/CustomProvider.cjs index 153137e09..bd34d31c6 100644 --- a/examples/companion-custom-provider/server/CustomProvider.cjs +++ b/examples/companion-custom-provider/server/CustomProvider.cjs @@ -38,7 +38,6 @@ class MyCustomProvider { return 'myunsplash' } - // eslint-disable-next-line class-methods-use-this async list({ token, directory }) { const path = directory ? `/${directory}/photos` : '' @@ -55,7 +54,6 @@ class MyCustomProvider { return adaptData(await resp.json()) } - // eslint-disable-next-line class-methods-use-this async download({ id, token }) { const resp = await fetch(`${BASE_URL}/photos/${id}`, { headers: { diff --git a/examples/xhr-bundle/server.cjs b/examples/xhr-bundle/server.cjs index 871ba8f27..75738a06c 100644 --- a/examples/xhr-bundle/server.cjs +++ b/examples/xhr-bundle/server.cjs @@ -9,7 +9,6 @@ const upload = multer({ function uploadRoute(req, res) { res.json({ files: req.files.map((file) => { - // eslint-disable-next-line no-param-reassign delete file.buffer return file }), diff --git a/packages/@uppy/companion-client/src/getAllowedHosts.test.ts b/packages/@uppy/companion-client/src/getAllowedHosts.test.ts index 74beab961..d82c31583 100644 --- a/packages/@uppy/companion-client/src/getAllowedHosts.test.ts +++ b/packages/@uppy/companion-client/src/getAllowedHosts.test.ts @@ -36,13 +36,14 @@ describe('isOriginAllowed', () => { expect(isOriginAllowed('a', [/^.+$/])).toBeTruthy() expect(isOriginAllowed('a', ['^.+$'])).toBeTruthy() expect( - isOriginAllowed('www.transloadit.com', ['www\\.transloadit\\.com']), + isOriginAllowed('www.transloadit.com', ['^www\\.transloadit\\.com$']), ).toBeTruthy() expect( - isOriginAllowed('www.transloadit.com', ['transloadit\\.com']), + isOriginAllowed('www.transloadit.com', ['^transloadit\\.com$']), ).toBeFalsy() expect(isOriginAllowed('match', ['fail', 'match'])).toBeTruthy() - // todo maybe next major: - // expect(isOriginAllowed('www.transloadit.com', ['\\.transloadit\\.com$'])).toBeTruthy() + expect( + isOriginAllowed('www.transloadit.com', ['\\.transloadit\\.com$']), + ).toBeTruthy() }) }) diff --git a/packages/@uppy/companion-client/src/getAllowedHosts.ts b/packages/@uppy/companion-client/src/getAllowedHosts.ts index d32394d2f..5487dca03 100644 --- a/packages/@uppy/companion-client/src/getAllowedHosts.ts +++ b/packages/@uppy/companion-client/src/getAllowedHosts.ts @@ -5,8 +5,7 @@ function escapeRegex(string: string) { function wrapInRegex(value?: string | RegExp): RegExp | undefined { if (typeof value === 'string') { - // TODO in the next major we should change this to `new RegExp(value)` so that the user can control start/end characters - return new RegExp(`^${value}$`) // throws if invalid regex + return new RegExp(value) // throws if invalid regex } if (value instanceof RegExp) { return value diff --git a/packages/@uppy/companion/src/server/Uploader.js b/packages/@uppy/companion/src/server/Uploader.js index 54cc35cf8..4ba487454 100644 --- a/packages/@uppy/companion/src/server/Uploader.js +++ b/packages/@uppy/companion/src/server/Uploader.js @@ -82,7 +82,6 @@ function validateOptions(options) { } // validate protocol - // @todo this validation should not be conditional once the protocol field is mandatory if ( options.protocol && !Object.keys(PROTOCOLS).some((key) => PROTOCOLS[key] === options.protocol) @@ -227,8 +226,6 @@ class Uploader { } _getUploadProtocol() { - // todo a default protocol should not be set. We should ensure that the user specifies their protocol. - // after we drop old versions of uppy client we can remove this return this.options.protocol || PROTOCOLS.multipart } diff --git a/packages/@uppy/companion/src/server/controllers/get.js b/packages/@uppy/companion/src/server/controllers/get.js index a30bd3c82..f8ee4804c 100644 --- a/packages/@uppy/companion/src/server/controllers/get.js +++ b/packages/@uppy/companion/src/server/controllers/get.js @@ -5,25 +5,14 @@ const { respondWithError } = require('../provider/error') async function get(req, res) { const { id } = req.params const { providerUserSession } = req.companion - const { accessToken } = providerUserSession const { provider } = req.companion async function getSize() { - return provider.size({ - id, - token: accessToken, - providerUserSession, - query: req.query, - }) + return provider.size({ id, providerUserSession, query: req.query }) } const download = () => - provider.download({ - id, - token: accessToken, - providerUserSession, - query: req.query, - }) + provider.download({ id, providerUserSession, query: req.query }) try { await startDownUpload({ req, res, getSize, download }) diff --git a/packages/@uppy/companion/src/server/controllers/list.js b/packages/@uppy/companion/src/server/controllers/list.js index 1067b744a..2f3233f83 100644 --- a/packages/@uppy/companion/src/server/controllers/list.js +++ b/packages/@uppy/companion/src/server/controllers/list.js @@ -2,13 +2,10 @@ const { respondWithError } = require('../provider/error') async function list({ query, params, companion }, res, next) { const { providerUserSession } = companion - const { accessToken } = providerUserSession try { - // todo remove backward compat `token` param from all provider methods (because it can be found in providerUserSession) const data = await companion.provider.list({ companion, - token: accessToken, providerUserSession, directory: params.id, query, diff --git a/packages/@uppy/companion/src/server/controllers/logout.js b/packages/@uppy/companion/src/server/controllers/logout.js index ad24f715d..d7e4b5e31 100644 --- a/packages/@uppy/companion/src/server/controllers/logout.js +++ b/packages/@uppy/companion/src/server/controllers/logout.js @@ -23,9 +23,7 @@ async function logout(req, res, next) { } try { - const { accessToken } = providerUserSession const data = await companion.provider.logout({ - token: accessToken, providerUserSession, companion, }) diff --git a/packages/@uppy/companion/src/server/controllers/thumbnail.js b/packages/@uppy/companion/src/server/controllers/thumbnail.js index 25a4063c3..e779f4359 100644 --- a/packages/@uppy/companion/src/server/controllers/thumbnail.js +++ b/packages/@uppy/companion/src/server/controllers/thumbnail.js @@ -8,12 +8,10 @@ const { respondWithError } = require('../provider/error') async function thumbnail(req, res, next) { const { id } = req.params const { provider, providerUserSession } = req.companion - const { accessToken } = providerUserSession try { const { stream, contentType } = await provider.thumbnail({ id, - token: accessToken, providerUserSession, }) if (contentType != null) res.set('Content-Type', contentType) diff --git a/packages/@uppy/companion/src/server/helpers/request.js b/packages/@uppy/companion/src/server/helpers/request.js index 001c05e33..5f352c7c1 100644 --- a/packages/@uppy/companion/src/server/helpers/request.js +++ b/packages/@uppy/companion/src/server/helpers/request.js @@ -181,8 +181,6 @@ exports.getURLMeta = async ( } if (urlMeta.statusCode >= 300) { - // @todo possibly set a status code in the error object to get a more helpful - // hint at what the cause of error is. throw new Error(`URL server responded with status: ${urlMeta.statusCode}`) } diff --git a/packages/@uppy/companion/src/server/helpers/utils.js b/packages/@uppy/companion/src/server/helpers/utils.js index d135df079..cb3d7b4d1 100644 --- a/packages/@uppy/companion/src/server/helpers/utils.js +++ b/packages/@uppy/companion/src/server/helpers/utils.js @@ -1,5 +1,4 @@ const crypto = require('node:crypto') -const logger = require('../logger.js') const authTagLength = 16 const nonceLength = 16 @@ -120,43 +119,6 @@ module.exports.encrypt = (input, secret) => { return `${nonce.toString('hex')}${encrypted.toString('base64url')}` } -// todo backwards compat for old tokens - remove in the future -function compatDecrypt(encrypted, secret) { - // Need at least 32 chars for the iv - if (encrypted.length < 32) { - throw new Error( - 'Invalid encrypted value. Maybe it was generated with an old Companion version?', - ) - } - - // NOTE: The first 32 characters are the iv, in hex format. The rest is the encrypted string, in base64 format. - const iv = Buffer.from(encrypted.slice(0, 32), 'hex') - const encryptionWithoutIv = encrypted.slice(32) - - let decipher - try { - const secretHashed = crypto.createHash('sha256') - secretHashed.update(secret) - decipher = crypto.createDecipheriv('aes256', secretHashed.digest(), iv) - } catch (err) { - if (err.code === 'ERR_CRYPTO_INVALID_IV') { - throw new Error('Invalid initialization vector') - } else { - throw err - } - } - - const urlDecode = (encoded) => - encoded.replace(/-/g, '+').replace(/_/g, '/').replace(/~/g, '=') - let decrypted = decipher.update( - urlDecode(encryptionWithoutIv), - 'base64', - 'utf8', - ) - decrypted += decipher.final('utf8') - return decrypted -} - /** * Decrypt an iv-prefixed or string with AES256. The iv should be in the first 32 hex characters. * @@ -165,47 +127,41 @@ function compatDecrypt(encrypted, secret) { * @returns {string} Decrypted value. */ module.exports.decrypt = (encrypted, secret) => { - try { - const nonceHexLength = nonceLength * 2 // because hex encoding uses 2 bytes per byte + const nonceHexLength = nonceLength * 2 // because hex encoding uses 2 bytes per byte - // NOTE: The first 32 characters are the nonce, in hex format. - const nonce = Buffer.from(encrypted.slice(0, nonceHexLength), 'hex') - // The rest is the encrypted string, in base64url format. - const encryptionWithoutNonce = Buffer.from( - encrypted.slice(nonceHexLength), - 'base64url', + // NOTE: The first 32 characters are the nonce, in hex format. + const nonce = Buffer.from(encrypted.slice(0, nonceHexLength), 'hex') + // The rest is the encrypted string, in base64url format. + const encryptionWithoutNonce = Buffer.from( + encrypted.slice(nonceHexLength), + 'base64url', + ) + // The last 16 bytes of the rest is the authentication tag + const authTag = encryptionWithoutNonce.subarray(-authTagLength) + // and the rest (from beginning) is the encrypted data + const encryptionWithoutNonceAndTag = encryptionWithoutNonce.subarray( + 0, + -authTagLength, + ) + + if (nonce.length < nonceLength) { + throw new Error( + 'Invalid encrypted value. Maybe it was generated with an old Companion version?', ) - // The last 16 bytes of the rest is the authentication tag - const authTag = encryptionWithoutNonce.subarray(-authTagLength) - // and the rest (from beginning) is the encrypted data - const encryptionWithoutNonceAndTag = encryptionWithoutNonce.subarray( - 0, - -authTagLength, - ) - - if (nonce.length < nonceLength) { - throw new Error( - 'Invalid encrypted value. Maybe it was generated with an old Companion version?', - ) - } - - const { key, iv } = createSecrets(secret, nonce) - - const decipher = crypto.createDecipheriv('aes-256-ccm', key, iv, { - authTagLength, - }) - decipher.setAuthTag(authTag) - - const decrypted = Buffer.concat([ - decipher.update(encryptionWithoutNonceAndTag), - decipher.final(), - ]) - return decrypted.toString('utf8') - } catch (err) { - // todo backwards compat for old tokens - remove in the future - logger.info('Failed to decrypt - trying old encryption format instead', err) - return compatDecrypt(encrypted, secret) } + + const { key, iv } = createSecrets(secret, nonce) + + const decipher = crypto.createDecipheriv('aes-256-ccm', key, iv, { + authTagLength, + }) + decipher.setAuthTag(authTag) + + const decrypted = Buffer.concat([ + decipher.update(encryptionWithoutNonceAndTag), + decipher.final(), + ]) + return decrypted.toString('utf8') } module.exports.defaultGetKey = ({ filename }) => { diff --git a/packages/@uppy/companion/src/server/provider/Provider.js b/packages/@uppy/companion/src/server/provider/Provider.js index 154246be8..998fc210b 100644 --- a/packages/@uppy/companion/src/server/provider/Provider.js +++ b/packages/@uppy/companion/src/server/provider/Provider.js @@ -74,7 +74,6 @@ class Provider { * @returns {Promise} */ async deauthorizationCallback(options) { - // @todo consider doing something like throw new NotImplementedError() instead throw new Error('method not implemented') } diff --git a/packages/@uppy/companion/src/server/provider/box/index.js b/packages/@uppy/companion/src/server/provider/box/index.js index 70b22806b..32283565a 100644 --- a/packages/@uppy/companion/src/server/provider/box/index.js +++ b/packages/@uppy/companion/src/server/provider/box/index.js @@ -56,10 +56,15 @@ class Box extends Provider { * @param {object} options * @param {string} options.directory * @param {any} options.query - * @param {string} options.token + * @param {{ accessToken: string }} options.providerUserSession * @param {unknown} options.companion */ - async list({ directory, token, query, companion }) { + async list({ + directory, + providerUserSession: { accessToken: token }, + query, + companion, + }) { return this.#withErrorHandling('provider.box.list.error', async () => { const [userInfo, files] = await Promise.all([ getUserInfo({ token }), @@ -70,7 +75,7 @@ class Box extends Provider { }) } - async download({ id, token }) { + async download({ id, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling('provider.box.download.error', async () => { const stream = (await getClient({ token })).stream.get( `files/${id}/content`, @@ -82,7 +87,7 @@ class Box extends Provider { }) } - async thumbnail({ id, token }) { + async thumbnail({ id, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling('provider.box.thumbnail.error', async () => { const extension = 'jpg' // you can set this to png to more easily reproduce http 202 retry-after @@ -111,7 +116,7 @@ class Box extends Provider { }) } - async size({ id, token }) { + async size({ id, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling('provider.box.size.error', async () => { const { size } = await (await getClient({ token })) .get(`files/${id}`, { responseType: 'json' }) @@ -120,7 +125,7 @@ class Box extends Provider { }) } - logout({ companion, token }) { + logout({ companion, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling('provider.box.logout.error', async () => { const { key, secret } = companion.options.providerOptions.box await (await getClient({ token })).post('oauth2/revoke', { diff --git a/packages/@uppy/companion/src/server/provider/credentials.js b/packages/@uppy/companion/src/server/provider/credentials.js index e28efe2e9..c4ee5db03 100644 --- a/packages/@uppy/companion/src/server/provider/credentials.js +++ b/packages/@uppy/companion/src/server/provider/credentials.js @@ -187,8 +187,6 @@ exports.getCredentialsOverrideMiddleware = (providers, companionOptions) => { next() } catch (keyErr) { - // TODO we should return an html page here that can communicate the error - // back to the Uppy client, just like /send-token does res.send(` diff --git a/packages/@uppy/companion/src/server/provider/dropbox/index.js b/packages/@uppy/companion/src/server/provider/dropbox/index.js index 57204b1c5..7095f56d6 100644 --- a/packages/@uppy/companion/src/server/provider/dropbox/index.js +++ b/packages/@uppy/companion/src/server/provider/dropbox/index.js @@ -123,7 +123,7 @@ class DropBox extends Provider { async list(options) { return this.#withErrorHandling('provider.dropbox.list.error', async () => { const { client, userInfo } = await getClient({ - token: options.token, + token: options.providerUserSession.accessToken, namespaced: true, }) @@ -133,7 +133,7 @@ class DropBox extends Provider { }) } - async download({ id, token }) { + async download({ id, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling( 'provider.dropbox.download.error', async () => { @@ -155,7 +155,7 @@ class DropBox extends Provider { ) } - async thumbnail({ id, token }) { + async thumbnail({ id, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling( 'provider.dropbox.thumbnail.error', async () => { @@ -180,7 +180,7 @@ class DropBox extends Provider { ) } - async size({ id, token }) { + async size({ id, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling('provider.dropbox.size.error', async () => { const { size } = await ( await getClient({ token, namespaced: true }) @@ -194,7 +194,7 @@ class DropBox extends Provider { }) } - async logout({ token }) { + async logout({ providerUserSession: { accessToken: token } }) { return this.#withErrorHandling( 'provider.dropbox.logout.error', async () => { diff --git a/packages/@uppy/companion/src/server/provider/facebook/index.js b/packages/@uppy/companion/src/server/provider/facebook/index.js index 38b5a918b..92911a9b6 100644 --- a/packages/@uppy/companion/src/server/provider/facebook/index.js +++ b/packages/@uppy/companion/src/server/provider/facebook/index.js @@ -70,7 +70,11 @@ class Facebook extends Provider { return 'facebook' } - async list({ directory, token, query = { cursor: null } }) { + async list({ + directory, + providerUserSession: { accessToken: token }, + query = { cursor: null }, + }) { return this.#withErrorHandling('provider.facebook.list.error', async () => { const qs = { fields: 'name,cover_photo,created_time,type' } @@ -100,7 +104,7 @@ class Facebook extends Provider { }) } - async download({ id, token }) { + async download({ id, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling( 'provider.facebook.download.error', async () => { @@ -121,7 +125,7 @@ class Facebook extends Provider { throw new Error('call to thumbnail is not implemented') } - async logout({ token }) { + async logout({ providerUserSession: { accessToken: token } }) { return this.#withErrorHandling( 'provider.facebook.logout.error', async () => { diff --git a/packages/@uppy/companion/src/server/provider/google/drive/index.js b/packages/@uppy/companion/src/server/provider/google/drive/index.js index 1a307d45f..1b16edcf1 100644 --- a/packages/@uppy/companion/src/server/provider/google/drive/index.js +++ b/packages/@uppy/companion/src/server/provider/google/drive/index.js @@ -120,7 +120,9 @@ class Drive extends Provider { async () => { const directory = options.directory || 'root' const query = options.query || {} - const { token } = options + const { + providerUserSession: { accessToken: token }, + } = options const isRoot = directory === 'root' const isVirtualSharedDirRoot = directory === VIRTUAL_SHARED_DIR @@ -204,7 +206,7 @@ class Drive extends Provider { ) } - async download({ id, token }) { + async download({ id, providerUserSession: { accessToken: token } }) { if (mockAccessTokenExpiredError != null) { logger.warn(`Access token: ${token}`) diff --git a/packages/@uppy/companion/src/server/provider/google/index.js b/packages/@uppy/companion/src/server/provider/google/index.js index af23c4cfa..769ae8e37 100644 --- a/packages/@uppy/companion/src/server/provider/google/index.js +++ b/packages/@uppy/companion/src/server/provider/google/index.js @@ -36,7 +36,7 @@ async function refreshToken({ ) } -async function logout({ token }) { +async function logout({ providerUserSession: { accessToken: token } }) { return withGoogleErrorHandling( 'google', 'provider.google.logout.error', diff --git a/packages/@uppy/companion/src/server/provider/instagram/graph/index.js b/packages/@uppy/companion/src/server/provider/instagram/graph/index.js index b747e843c..1b4551f07 100644 --- a/packages/@uppy/companion/src/server/provider/instagram/graph/index.js +++ b/packages/@uppy/companion/src/server/provider/instagram/graph/index.js @@ -40,7 +40,11 @@ class Instagram extends Provider { return 'instagram' } - async list({ directory, token, query = { cursor: null } }) { + async list({ + directory, + providerUserSession: { accessToken: token }, + query = { cursor: null }, + }) { return this.#withErrorHandling( 'provider.instagram.list.error', async () => { @@ -69,7 +73,7 @@ class Instagram extends Provider { ) } - async download({ id, token }) { + async download({ id, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling( 'provider.instagram.download.error', async () => { diff --git a/packages/@uppy/companion/src/server/provider/onedrive/index.js b/packages/@uppy/companion/src/server/provider/onedrive/index.js index 4467d98b8..c592f48f1 100644 --- a/packages/@uppy/companion/src/server/provider/onedrive/index.js +++ b/packages/@uppy/companion/src/server/provider/onedrive/index.js @@ -37,9 +37,13 @@ class OneDrive extends Provider { * @param {object} options * @param {string} options.directory * @param {any} options.query - * @param {string} options.token + * @param {{ accessToken: string }} options.providerUserSession */ - async list({ directory, query, token }) { + async list({ + directory, + query, + providerUserSession: { accessToken: token }, + }) { return this.#withErrorHandling('provider.onedrive.list.error', async () => { const path = directory ? `items/${directory}` : 'root' // https://learn.microsoft.com/en-us/graph/query-parameters?tabs=http#top-parameter @@ -66,7 +70,7 @@ class OneDrive extends Provider { }) } - async download({ id, token, query }) { + async download({ id, providerUserSession: { accessToken: token }, query }) { return this.#withErrorHandling( 'provider.onedrive.download.error', async () => { @@ -89,7 +93,7 @@ class OneDrive extends Provider { throw new Error('call to thumbnail is not implemented') } - async size({ id, query, token }) { + async size({ id, query, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling('provider.onedrive.size.error', async () => { const { size } = await (await getClient({ token })) .get(`${getRootPath(query)}/items/${id}`, { responseType: 'json' }) diff --git a/packages/@uppy/companion/src/server/provider/unsplash/index.js b/packages/@uppy/companion/src/server/provider/unsplash/index.js index 607f4ee63..29b9a5bb6 100644 --- a/packages/@uppy/companion/src/server/provider/unsplash/index.js +++ b/packages/@uppy/companion/src/server/provider/unsplash/index.js @@ -23,7 +23,10 @@ const getPhotoMeta = async (client, id) => * Adapter for API https://api.unsplash.com */ class Unsplash extends Provider { - async list({ token, query = { cursor: null, q: null } }) { + async list({ + providerUserSession: { accessToken: token }, + query = { cursor: null, q: null }, + }) { if (typeof query.q !== 'string') { throw new ProviderApiError('Search query missing', 400) } @@ -39,7 +42,7 @@ class Unsplash extends Provider { }) } - async download({ id, token }) { + async download({ id, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling( 'provider.unsplash.download.error', async () => { diff --git a/packages/@uppy/companion/src/server/provider/webdav/index.js b/packages/@uppy/companion/src/server/provider/webdav/index.js index 79e265cb2..8ca66f231 100644 --- a/packages/@uppy/companion/src/server/provider/webdav/index.js +++ b/packages/@uppy/companion/src/server/provider/webdav/index.js @@ -69,7 +69,6 @@ class WebdavProvider extends Provider { 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 } } @@ -168,7 +167,7 @@ class WebdavProvider extends Provider { 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) + err2 = new ProviderApiError('WebDAV API error', err.status) } logger.error(err2, tag) throw err2 diff --git a/packages/@uppy/companion/src/server/provider/zoom/index.js b/packages/@uppy/companion/src/server/provider/zoom/index.js index 82171ed25..5fc37955a 100644 --- a/packages/@uppy/companion/src/server/provider/zoom/index.js +++ b/packages/@uppy/companion/src/server/provider/zoom/index.js @@ -45,7 +45,9 @@ class Zoom extends Provider { async list(options) { return this.#withErrorHandling('provider.zoom.list.error', async () => { - const { token } = options + const { + providerUserSession: { accessToken: token }, + } = options const query = options.query || {} const meetingId = options.directory || '' const requestedYear = query.year ? parseInt(query.year, 10) : null @@ -141,7 +143,11 @@ class Zoom extends Provider { }) } - async download({ id: meetingId, token, query }) { + async download({ + id: meetingId, + providerUserSession: { accessToken: token }, + query, + }) { return this.#withErrorHandling('provider.zoom.download.error', async () => { // meeting id + file id required // cc files don't have an ID or size @@ -167,7 +173,11 @@ class Zoom extends Provider { }) } - async size({ id: meetingId, token, query }) { + async size({ + id: meetingId, + providerUserSession: { accessToken: token }, + query, + }) { return this.#withErrorHandling('provider.zoom.size.error', async () => { const client = await getClient({ token }) const { recordingStart, recordingId: fileId } = query @@ -183,7 +193,7 @@ class Zoom extends Provider { }) } - async logout({ companion, token }) { + async logout({ companion, providerUserSession: { accessToken: token } }) { return this.#withErrorHandling('provider.zoom.logout.error', async () => { const { key, secret } = await companion.getProviderCredentials() diff --git a/packages/@uppy/companion/test/__tests__/deauthorization.js b/packages/@uppy/companion/test/__tests__/deauthorization.js index e8c468d55..e1f77924f 100644 --- a/packages/@uppy/companion/test/__tests__/deauthorization.js +++ b/packages/@uppy/companion/test/__tests__/deauthorization.js @@ -13,16 +13,13 @@ describe('handle deauthorization callback', () => { nock('https://api.zoom.us').post('/oauth/data/compliance').reply(200) test('providers without support for callback endpoint', () => { - return ( - request(authServer) - .post('/dropbox/deauthorization/callback') - .set('Content-Type', 'application/json') - .send({ - foo: 'bar', - }) - // @todo consider receiving 501 instead - .expect(500) - ) + return request(authServer) + .post('/dropbox/deauthorization/callback') + .set('Content-Type', 'application/json') + .send({ + foo: 'bar', + }) + .expect(500) }) test('validate that request credentials match', () => { diff --git a/packages/@uppy/webcam/src/CameraScreen.tsx b/packages/@uppy/webcam/src/CameraScreen.tsx index 945e1aba0..717b4ad31 100644 --- a/packages/@uppy/webcam/src/CameraScreen.tsx +++ b/packages/@uppy/webcam/src/CameraScreen.tsx @@ -117,14 +117,11 @@ class CameraScreen extends Component { /> ) : ( - // eslint-disable-next-line jsx-a11y/media-has-caption