From 9b0d7f9b753dd887425afc1144762522811dbb02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:35:43 +0200 Subject: [PATCH 1/7] Bump docker/build-push-action from 6.1.0 to 6.2.0 (#5290) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/31159d49c0d4756269a0940a750801a1ea5d7003...15560696de535e4014efeff63c48f16952e52dd1) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/companion-deploy.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/companion-deploy.yml b/.github/workflows/companion-deploy.yml index 6b476f127..ddf98e2cb 100644 --- a/.github/workflows/companion-deploy.yml +++ b/.github/workflows/companion-deploy.yml @@ -63,7 +63,7 @@ jobs: username: ${{secrets.DOCKER_USERNAME}} password: ${{secrets.DOCKER_PASSWORD}} - name: Build and push - uses: docker/build-push-action@31159d49c0d4756269a0940a750801a1ea5d7003 # v6.1.0 + uses: docker/build-push-action@15560696de535e4014efeff63c48f16952e52dd1 # v6.2.0 with: push: true context: . diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 41683f88b..2a44c26f0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -159,7 +159,7 @@ jobs: username: ${{secrets.DOCKER_USERNAME}} password: ${{secrets.DOCKER_PASSWORD}} - name: Build and push - uses: docker/build-push-action@31159d49c0d4756269a0940a750801a1ea5d7003 # v6.1.0 + uses: docker/build-push-action@15560696de535e4014efeff63c48f16952e52dd1 # v6.2.0 with: push: true context: . From 6588ab9275af50c1bff30e9b60244d33ecaef79d Mon Sep 17 00:00:00 2001 From: Evgenia Karunus Date: Tue, 2 Jul 2024 16:59:52 +0500 Subject: [PATCH 2/7] `uppy.io/docs` - fix typos/broken links (#5296) * `https://uppy.io/docs/dragdrop` is a broken link * `angular.mdx` - typo * `angular.mdx` - another typo --- docs/framework-integrations/angular.mdx | 2 +- packages/@uppy/drag-drop/README.md | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/framework-integrations/angular.mdx b/docs/framework-integrations/angular.mdx index e2f9ec3fb..6c6b74765 100644 --- a/docs/framework-integrations/angular.mdx +++ b/docs/framework-integrations/angular.mdx @@ -11,7 +11,7 @@ import TabItem from '@theme/TabItem'; ## When should I use it? -When you are using the Angular framework and you wouldl like to use on of the UI +When you are using the Angular framework and you would like to use one of the UI components. ## Install diff --git a/packages/@uppy/drag-drop/README.md b/packages/@uppy/drag-drop/README.md index fa6619552..7566041fc 100644 --- a/packages/@uppy/drag-drop/README.md +++ b/packages/@uppy/drag-drop/README.md @@ -9,8 +9,7 @@ Droppable zone UI for Uppy. Drag and drop files into it to upload. -**[Read the docs](https://uppy.io/docs/dragdrop)** | -**[Try it](https://uppy.io/examples/dragdrop/)** +**[Read the docs](https://uppy.io/docs/drag-drop/)** Uppy is being developed by the folks at [Transloadit](https://transloadit.com), a versatile file encoding service. @@ -41,7 +40,7 @@ Transloadit’s CDN: Edgly. In that case `Uppy` will attach itself to the global ## Documentation Documentation for this plugin can be found on the -[Uppy website](https://uppy.io/docs/dragdrop). +[Uppy website](https://uppy.io/docs/drag-drop/). ## License From 604fddeb263f9adda273a52955ac603154a07ec7 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Tue, 2 Jul 2024 15:28:24 +0200 Subject: [PATCH 3/7] meta: add dark-mode Transloadit logo in README (#5291) --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 52e4ae11d..dc87d3331 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,15 @@ about more important problems than building a file uploader. **[Read the docs](https://uppy.io/docs)** | **[Try Uppy](https://uppy.io/examples/dashboard/)** - +

+ + + + + Developed by Transloadit + + +

Uppy is being developed by the folks at [Transloadit](https://transloadit.com), a versatile API to handle any file in your app. From e849827824239b049af10f2f0622ee2b9f234660 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 2 Jul 2024 15:33:55 +0200 Subject: [PATCH 4/7] @uppy/companion: add `oauthOrigin` option (#5297) Co-authored-by: Mikael Finstad --- .env.example | 1 + docs/companion.md | 15 +++++++++++++++ e2e/start-companion-with-load-balancer.mjs | 1 + .../@uppy/companion-client/src/Provider.ts | 1 + .../src/server/controllers/connect.js | 19 ++++++++++++++++--- .../@uppy/companion/src/standalone/helper.js | 3 +++ .../companion/test/__tests__/uploader.js | 1 + packages/@uppy/companion/test/mockserver.js | 2 ++ 8 files changed, 40 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index c00e1b2a9..a1ea58cc7 100644 --- a/.env.example +++ b/.env.example @@ -11,6 +11,7 @@ COMPANION_PORT=3020 COMPANION_CLIENT_ORIGINS= COMPANION_SECRET=development COMPANION_PREAUTH_SECRET=development2 +COMPANION_OAUTH_ORIGIN=* # NOTE: Only enable this in development. Enabling it in production is a security risk COMPANION_ALLOW_LOCAL_URLS=true diff --git a/docs/companion.md b/docs/companion.md index 8bd6462a3..c27063a17 100644 --- a/docs/companion.md +++ b/docs/companion.md @@ -343,6 +343,21 @@ which has only the secret, nothing else. ::: +### `oauthOrigin` `COMPANION_OAUTH_ORIGIN` + +:::caution + +Setting this option is strongly recommended. If left unset (or set to `'*'`), +your app could be impersonated. + +::: + +An [origin](https://developer.mozilla.org/en-US/docs/Glossary/Origin) specifying +allowed origins, or an array of origins (comma-separated origins in +`COMPANION_OAUTH_ORIGIN`). Any browser request from an origin that is not listed +will not receive OAuth2 tokens, and the OAuth request won’t complete. Set it to +`'*'` to allow all origins (not recommended). Default: `'*'`. + #### `uploadUrls` `COMPANION_UPLOAD_URLS` An allowlist (array) of strings (exact URLs) or regular expressions. Companion diff --git a/e2e/start-companion-with-load-balancer.mjs b/e2e/start-companion-with-load-balancer.mjs index a0f2be79b..a29cd632c 100755 --- a/e2e/start-companion-with-load-balancer.mjs +++ b/e2e/start-companion-with-load-balancer.mjs @@ -66,6 +66,7 @@ const startCompanion = ({ name, port }) => { COMPANION_PREAUTH_SECRET: 'development', // multi instance will not work without secret set COMPANION_ALLOW_LOCAL_URLS: 'true', COMPANION_LOGGER_PROCESS_NAME: name, + COMPANION_OAUTH_ORIGIN: '*', }, }) // Adding a `then` property so the return value is awaitable: diff --git a/packages/@uppy/companion-client/src/Provider.ts b/packages/@uppy/companion-client/src/Provider.ts index aad0ef42e..de46726ed 100644 --- a/packages/@uppy/companion-client/src/Provider.ts +++ b/packages/@uppy/companion-client/src/Provider.ts @@ -171,6 +171,7 @@ export default class Provider }): string { const params = new URLSearchParams({ ...query, + // This is only used for Companion instances configured to accept multiple origins. state: btoa(JSON.stringify({ origin: getOrigin() })), ...this.authQuery({ authFormData }), }) diff --git a/packages/@uppy/companion/src/server/controllers/connect.js b/packages/@uppy/companion/src/server/controllers/connect.js index 7018e18e3..fa135c48d 100644 --- a/packages/@uppy/companion/src/server/controllers/connect.js +++ b/packages/@uppy/companion/src/server/controllers/connect.js @@ -13,12 +13,25 @@ const queryString = (params, prefix = '?') => { * @param {object} res */ module.exports = function connect(req, res) { - const { secret } = req.companion.options + const { secret, oauthOrigin } = req.companion.options const stateObj = oAuthState.generateState() - if (req.query.state) { + // not sure if we need to store origin in the session state (e.g. we could've just gotten it directly inside send-token) + // but we're afraid to change the logic there + if (oauthOrigin && !Array.isArray(oauthOrigin)) { + // If the server only allows a single origin, we ignore the client-supplied + // origin from query because we don't need it. + stateObj.origin = oauthOrigin + } else if (oauthOrigin && oauthOrigin.length < 2) { + // eslint-disable-next-line prefer-destructuring + stateObj.origin = oauthOrigin[0] + } else { + // If we have multiple allowed origins, we need to check the client-supplied origin from query. + // If the client provides an untrusted origin, + // we want to send `undefined`. `undefined` means `/`, which is the same origin when passed to `postMessage`. + // https://html.spec.whatwg.org/multipage/web-messaging.html#dom-window-postmessage-options-dev const { origin } = JSON.parse(atob(req.query.state)) - stateObj.origin = origin + stateObj.origin = oauthOrigin ? oauthOrigin.find(o => o === origin) : origin } if (req.companion.options.server.oauthDomain) { diff --git a/packages/@uppy/companion/src/standalone/helper.js b/packages/@uppy/companion/src/standalone/helper.js index e8d7d7c0b..dbc3ab875 100644 --- a/packages/@uppy/companion/src/standalone/helper.js +++ b/packages/@uppy/companion/src/standalone/helper.js @@ -183,6 +183,9 @@ const getConfigFromEnv = () => { corsOrigins: getCorsOrigins(), testDynamicOauthCredentials: process.env.COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS === 'true', testDynamicOauthCredentialsSecret: process.env.COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS_SECRET, + oauthOrigin: process.env.COMPANION_OAUTH_ORIGIN?.includes(',') ? + process.env.COMPANION_OAUTH_ORIGIN.split(',') : + process.env.COMPANION_OAUTH_ORIGIN, } } diff --git a/packages/@uppy/companion/test/__tests__/uploader.js b/packages/@uppy/companion/test/__tests__/uploader.js index 8b29a3474..04e9320e1 100644 --- a/packages/@uppy/companion/test/__tests__/uploader.js +++ b/packages/@uppy/companion/test/__tests__/uploader.js @@ -18,6 +18,7 @@ afterAll(() => { process.env.COMPANION_DATADIR = './test/output' process.env.COMPANION_DOMAIN = 'localhost:3020' +process.env.COMPANION_OAUTH_ORIGIN = '*' const { companionOptions } = standalone() describe('uploader with tus protocol', () => { diff --git a/packages/@uppy/companion/test/mockserver.js b/packages/@uppy/companion/test/mockserver.js index 7bdf519f8..6c0ee2f70 100644 --- a/packages/@uppy/companion/test/mockserver.js +++ b/packages/@uppy/companion/test/mockserver.js @@ -40,6 +40,8 @@ const defaultEnv = { COMPANION_PERIODIC_PING_URLS: '', COMPANION_CLIENT_SOCKET_CONNECT_TIMEOUT: '', + + COMPANION_OAUTH_ORIGIN: '*', } function updateEnv (env) { From 6f889ec4352e16db88fcd38cc932c2bdcb20949b Mon Sep 17 00:00:00 2001 From: Augustine Smith Date: Tue, 2 Jul 2024 13:34:15 +0000 Subject: [PATCH 5/7] @uppy/core: add `clearUploadedFiles` to type definition (#5295) --- packages/@uppy/core/src/Uppy.test.ts | 51 ++++++++++++++++++++++++++++ packages/@uppy/core/types/index.d.ts | 2 ++ 2 files changed, 53 insertions(+) diff --git a/packages/@uppy/core/src/Uppy.test.ts b/packages/@uppy/core/src/Uppy.test.ts index a6fe87034..443ef01cf 100644 --- a/packages/@uppy/core/src/Uppy.test.ts +++ b/packages/@uppy/core/src/Uppy.test.ts @@ -1971,6 +1971,57 @@ describe('src/Core', () => { }) }) + describe('clearUploadedFiles', () => { + it('should reset state to default', () => { + const core = new Core() + core.addFile({ + source: 'vi', + name: 'foo.jpg', + type: 'image/jpeg', + data: testImage, + }) + core.addFile({ + source: 'vi', + name: 'foo2.jpg', + type: 'image/jpeg', + data: testImage, + }) + core.clearUploadedFiles() + expect(core.getState()).toMatchObject({ + totalProgress: 0, + allowNewUpload: true, + error: null, + recoveredState: null, + files: {}, + }) + }) + + it('should throw error if plugin does not allow removing files during an upload', () => { + const core = new Core() + const newState = { + capabilities: { + individualCancellation: false, + uploadProgress: true, + resumableUploads: false, + }, + currentUploads: { + upload1: { + fileIDs: [ + 'uppy-file1/jpg-1e-image/jpeg', + 'uppy-file2/jpg-1e-image/jpeg', + 'uppy-file3/jpg-1e-image/jpeg', + ], + }, + }, + } + // @ts-ignore + core.setState(newState) + expect(() => { + core.clearUploadedFiles() + }).toThrowError() + }) + }) + describe('checkRestrictions', () => { it('should enforce the maxNumberOfFiles rule', () => { const core = new Core({ diff --git a/packages/@uppy/core/types/index.d.ts b/packages/@uppy/core/types/index.d.ts index d23ea1113..199cce864 100644 --- a/packages/@uppy/core/types/index.d.ts +++ b/packages/@uppy/core/types/index.d.ts @@ -335,6 +335,8 @@ export class Uppy< resetProgress(): void + clearUploadedFiles(): void + addPreProcessor(fn: UploadHandler): void removePreProcessor(fn: UploadHandler): void From 392116898c565221e0e164f78ad776b86fdc46f2 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Tue, 2 Jul 2024 16:03:36 +0200 Subject: [PATCH 6/7] meta: fix broken workflow status badges in README (#5298) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dc87d3331..605b4935f 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,8 @@ Uppy is being developed by the folks at [Transloadit](https://transloadit.com), a versatile API to handle any file in your app. - - + +
TestsCI status for Uppy testsCI status for Companion testsCI status for browser tests
DeploysCI status for CDN deploymentCI status for Companion deploymentCI status for website deployment
TestsCI status for Uppy testsCI status for Companion testsCI status for browser tests
DeploysCI status for CDN deploymentCI status for Companion deploymentCI status for website deployment
## Example From 7c174e85b7c3eb28a9fdbf3fe9021315b38b9f9f Mon Sep 17 00:00:00 2001 From: Nadeem Reinhardt Date: Tue, 2 Jul 2024 07:13:35 -0700 Subject: [PATCH 7/7] @uppy/companion: add `s3.forcePathStyle` option (#5066) Co-authored-by: Antoine du Hamel --- .env.example | 2 ++ docs/companion.md | 6 ++++++ examples/aws-companion/server.cjs | 1 + examples/aws-nodejs/index.js | 1 + examples/digitalocean-spaces/server.cjs | 2 ++ packages/@uppy/companion/env_example | 1 + packages/@uppy/companion/src/server/s3-client.js | 1 + packages/@uppy/companion/src/standalone/helper.js | 1 + 8 files changed, 15 insertions(+) diff --git a/.env.example b/.env.example index a1ea58cc7..364b7e3e0 100644 --- a/.env.example +++ b/.env.example @@ -26,6 +26,8 @@ COMPANION_AWS_REGION="AWS REGION" COMPANION_AWS_PREFIX="OPTIONAL PREFIX" # to enable S3 Transfer Acceleration (default: false) # COMPANION_AWS_USE_ACCELERATE_ENDPOINT="false" +# to enable S3 path style uploads (default: false), this is useful for localstack support +# COMPANION_AWS_FORCE_PATH_STYLE="true" # to set X-Amz-Expires query param in presigned urls (in seconds, default: 800) # COMPANION_AWS_EXPIRES="800" # to set a canned ACL for uploaded objects: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl diff --git a/docs/companion.md b/docs/companion.md index c27063a17..f06292761 100644 --- a/docs/companion.md +++ b/docs/companion.md @@ -501,6 +501,12 @@ the following arguments: - metadata provided by the user for the file (will be `undefined` for local uploads) +#### `s3.forcePathStyle` `COMPANION_AWS_FORCE_PATH_STYLE` + +This adds support for setting the S3 client’s `forcePathStyle` option. That is +necessary to use Uppy/Companion alongside localstack in development +environments. **Default**: `false`. + ##### `s3.region` `COMPANION_AWS_REGION` The datacenter region where the target bucket is located. diff --git a/examples/aws-companion/server.cjs b/examples/aws-companion/server.cjs index 98dc31231..cf2b84357 100644 --- a/examples/aws-companion/server.cjs +++ b/examples/aws-companion/server.cjs @@ -35,6 +35,7 @@ const options = { bucket: process.env.COMPANION_AWS_BUCKET, region: process.env.COMPANION_AWS_REGION, endpoint: process.env.COMPANION_AWS_ENDPOINT, + forcePathStyle: process.env.COMPANION_AWS_FORCE_PATH_STYLE === 'true', }, server: { host: 'localhost:3020' }, filePath: DATA_DIR, diff --git a/examples/aws-nodejs/index.js b/examples/aws-nodejs/index.js index c067565d5..cb8c42cb1 100644 --- a/examples/aws-nodejs/index.js +++ b/examples/aws-nodejs/index.js @@ -61,6 +61,7 @@ function getS3Client () { accessKeyId: process.env.COMPANION_AWS_KEY, secretAccessKey: process.env.COMPANION_AWS_SECRET, }, + forcePathStyle: process.env.COMPANION_AWS_FORCE_PATH_STYLE === 'true', }) return s3Client } diff --git a/examples/digitalocean-spaces/server.cjs b/examples/digitalocean-spaces/server.cjs index dc369fa8b..e6d10ce97 100644 --- a/examples/digitalocean-spaces/server.cjs +++ b/examples/digitalocean-spaces/server.cjs @@ -14,6 +14,7 @@ const companion = require('../../packages/@uppy/companion') * - COMPANION_AWS_KEY - Your access key ID * - COMPANION_AWS_SECRET - Your secret access key * - COMPANION_AWS_BUCKET - Your space's name. + * - COMPANION_AWS_FORCE_PATH_STYLE - Indicates if s3ForcePathStyle should be used rather than subdomain for S3 buckets. */ if (!process.env.COMPANION_AWS_REGION) throw new Error('Missing Space region, please set the COMPANION_AWS_REGION environment variable (eg. "COMPANION_AWS_REGION=ams3")') @@ -43,6 +44,7 @@ const { app: companionApp } = companion.app({ secret: process.env.COMPANION_AWS_SECRET, bucket: process.env.COMPANION_AWS_BUCKET, region: process.env.COMPANION_AWS_REGION, + forcePathStyle: process.env.COMPANION_AWS_FORCE_PATH_STYLE === 'true', }, server: { host }, filePath: DATA_DIR, diff --git a/packages/@uppy/companion/env_example b/packages/@uppy/companion/env_example index 89e7b2298..08b3e0acf 100644 --- a/packages/@uppy/companion/env_example +++ b/packages/@uppy/companion/env_example @@ -39,6 +39,7 @@ COMPANION_AWS_BUCKET= COMPANION_AWS_ENDPOINT= COMPANION_AWS_REGION= COMPANION_AWS_PREFIX= +COMPANION_AWS_FORCE_PATH_STYLE="false" COMPANION_ZOOM_KEY= COMPANION_ZOOM_SECRET= diff --git a/packages/@uppy/companion/src/server/s3-client.js b/packages/@uppy/companion/src/server/s3-client.js index d5b5c48be..74717d238 100644 --- a/packages/@uppy/companion/src/server/s3-client.js +++ b/packages/@uppy/companion/src/server/s3-client.js @@ -29,6 +29,7 @@ module.exports = (companionOptions, createPresignedPostMode = false) => { /** @type {import('@aws-sdk/client-s3').S3ClientConfig} */ let s3ClientOptions = { region: s3.region, + forcePathStyle: Boolean(s3.forcePathStyle) } if (s3.useAccelerateEndpoint) { diff --git a/packages/@uppy/companion/src/standalone/helper.js b/packages/@uppy/companion/src/standalone/helper.js index dbc3ab875..347dec9cd 100644 --- a/packages/@uppy/companion/src/standalone/helper.js +++ b/packages/@uppy/companion/src/standalone/helper.js @@ -133,6 +133,7 @@ const getConfigFromEnv = () => { process.env.COMPANION_AWS_USE_ACCELERATE_ENDPOINT === 'true', expires: parseInt(process.env.COMPANION_AWS_EXPIRES || '800', 10), acl: process.env.COMPANION_AWS_ACL, + forcePathStyle: process.env.COMPANION_AWS_FORCE_PATH_STYLE === 'true', }, server: { host: process.env.COMPANION_DOMAIN,