diff --git a/.travis.yml b/.travis.yml index f39f223cd..c46f874b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: -- 6.11.3 +- 8.11.1 addons: apt: sources: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0667602aa..8071c191e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,7 +46,6 @@ PRs are welcome! Please do open an issue to discuss first if it's a big feature, - [ ] Prepare for (piwik-) tracking of usage of uppy ? see #83 - [ ] screenshot+screencast support similar to Webcam #148 - [ ] Webcam modes #198 -- [ ] feature: improved UI for Provider, Google Drive and Instagram, grid/list views - [ ] feature: React Native support - [ ] consider iframe / more security for Transloadit/Uppy integration widget and Uppy itself. Page can’t get files from Google Drive if its an iframe; possibility for folder restriction for provider plugins - [ ] It would be nice in the long run to have a dynamic package builder here right on the website where you can select the plugins you need/want and it builds and downloads a minified version of them? @@ -65,6 +64,10 @@ Sort of like jQuery UI: https://jqueryui.com/download/ - [ ] provider: Add Box - [ ] provider: change ProviderViews signature to receive Provider instance in second param. ref https://github.com/transloadit/uppy/pull/743#discussion_r180106070 - [ ] core: css-in-js, while keeping non-random classnames (ideally prefixed) and useful preprocessor features. also see simple https://github.com/codemirror/CodeMirror/blob/master/lib/codemirror.css (@arturi, @goto-bus-stop) +- [ ] webcam: Stop recording when file size is exceeded, should be possible given how the MediaRecorder API works +- [ ] dashboard: add option to disable uploading from local disk #657 +- [ ] dashboard: display data like image resolution on file cards #783 +- [ ] server: pass metadata to S3 `getKey` option, see https://github.com/transloadit/uppy/issues/689 ## 1.0 Goals @@ -72,14 +75,15 @@ What we need to do to release Uppy 1.0 - [ ] QA: test how everything works together: user experience from `npm install` to production build with Webpack, using in React/Redux environment (npm pack) - [ ] QA: test in multiple browsers and mobile devices again -- [ ] QA: test uppy server. benchmarks / stress test. multiple connections, different setups, large files (10 GB) +- [x] QA: test uppy server. benchmarks / stress test. multiple connections, different setups, large files (10 GB) - [ ] QA: tests for some plugins - [x] docs: on using plugins, all options, list of plugins, i18n - [ ] feature: preset for Transloadit that mimics jQuery SDK, check https://github.com/transloadit/jquery-sdk docs -- [ ] refactoring: possibly add CSS-in-JS +- [ ] refactoring: possibly add CSS-in-JS, style encapsulation - [x] refactoring: possibly switch from Yo-Yo to Preact, because it’s more stable, solves a few issues we are struggling with (onload being weird/hard/modern-browsers-only with bel; no way to pass refs to elements; extra network requests with base64 urls) and mature, “new standard”, larger community - [ ] refactoring: split uppy into small packages, lerna repo? - [x] QA: tests for core and utils +- [ ] feature: basic Reacte Native support - [x] feature: Redux and ReduxDevTools support (currently mirrors Uppy state to Redux) - [x] feature: beta file recovering after closed tab / browser crash - [x] feature: easy integration with React (UppyReact components) @@ -91,13 +95,17 @@ What we need to do to release Uppy 1.0 - [x] uppy-server: security audit - [x] uppy-server: storing tokens in user’s browser only (d040281cc9a63060e2f2685c16de0091aee5c7b4) +# 0.26.0 + +- [ ] dashboard: allow minimizing the Dashboard during upload (Uppy then becomes just a tiny progress indicator) (@arturi) + # next ## 0.25.0 -- [ ] dashboard: allow minimizing the Dashboard during upload (Uppy then becomes just a tiny progress indicator) (@arturi) +To Be Released: 2018-05-31. + - [ ] dashboard: cancel button for transloadit assemblies (@arturi, @goto-bus-stop) -- [ ] dashboard: option for Boolean metadata #454 (@arturi) - [ ] core: figure out per-plugin locales and i18n strings packs #491 - [ ] goldenretriever: confirmation before restore #443 - [ ] goldenretriever: add “ghost” files (@arturi) @@ -111,16 +119,46 @@ What we need to do to release Uppy 1.0 - [ ] uppy-server: benchmarks / stress test, large file, uppy-server / tus / S3 (10 GB) - [ ] uppy-server: document docker image setup for uppy-server (@ifedapoolarewaju) - [ ] xhrupload: emit a final `upload-progress` event in the XHRUpload plugin just before firing `upload-complete` (tus-js-client already handles this internally) (@arturi) -- [ ] core: add more mime-to-extension mappings from https://github.com/micnic/mime.json/blob/master/index.json (which ones?) (@arturi, @goto-bus-stop) +- [ ] core: add more mime-to-extension mappings from https://github.com/micnic/mime.json/blob/master/index.json (which ones?) # (@arturi, @goto-bus-stop) - [ ] providers: select files only after “select” is pressed, don’t add them right away when they are checked (keep a list of fileIds in state?); better UI + solves issue with autoProceed uploading in background, which is weird; re-read https://github.com/transloadit/uppy/pull/419#issuecomment-345210519 (@arturi, @goto-bus-stop) - [ ] tus: add `filename` and `filetype`, so that tus servers knows what headers to set https://github.com/tus/tus-js-client/commit/ebc5189eac35956c9f975ead26de90c896dbe360 - [ ] core: look into utilizing https://github.com/que-etc/resize-observer-polyfill for responsive components. See also https://github.com/transloadit/uppy/issues/750 -- [x] statusbar: add some spacing between text elements (#760 / @goto-bus-stop) -- [ ] docs: improve on React docs https://uppy.io/docs/react/, add small example for each component maybe? Dashboard, DragDrop, ProgressBar? No need to make separate pages for all of them, just headings on the same page. Right now docs are confusing, because they focus on DashboardModal. Also problems with syntax highlight on https://uppy.io/docs/react/dashboard-modal/. - [x] docs: add note in docs or solve the .run() issue, see #756 -- [x] core: add `uppy.getFiles()` method (@goto-bus-stop / #770) -- [x] dashboard: fix duplicate plugin IDs, see #702 (@goto-bus-stop) -- [x] react: update propTypes (#776 / @goto-bus-stop) +- [ ] core: use Browserslist config to share between PostCSS, Autoprefixer and Babel https://github.com/browserslist/browserslist, https://github.com/amilajack/eslint-plugin-compat (@arturi) +- [ ] core: utilize https://github.com/jonathantneal/postcss-preset-env, maybe https://github.com/jonathantneal/postcss-normalize (@arturi) +- [ ] docs: improve on React docs https://uppy.io/docs/react/, add small example for each component maybe? Dashboard, DragDrop, ProgressBar? No need to make separate pages for all of them, just headings on the same page. Right now docs are confusing, because they focus on DashboardModal. Also problems with syntax highlight on https://uppy.io/docs/react/dashboard-modal/ (@goto-bus-stop) +- [ ] core: customizing metadata fields, boolean metadata; see #809, #454 and related (@arturi) +- [ ] providers: Add user/account names to Uppy provider views (@ifedapoolarewaju) + +## 0.24.4 + +Released: 2018-05-14. + +- core: Pass `allowedFileTypes` and `maxNumberOfFiles` to input[type=file] in UI components: Dashboard, DragDrop, FileInput (#814 / @arturi) +- transloadit: Update Transloadit plugin's Uppy Server handling (#804 / @goto-bus-stop) +- tus: respect `limit` option for upload parameter requests (#817 / @ap--) +- docs: Explain name `metadata` vs. `$_FILES[]["name"]` (#1c1bf2e / @goto-bus-stop) +- dashboard: improve “powered by” icon (#0284c8e / @arturi) +- statusbar: add default string for cancel button (#822 / @mrbatista) + +## 0.24.3 + +Released: 2018-05-10. + +- core: add `uppy.getFiles()` method (@goto-bus-stop / #770) +- core: merge meta data when add file (#810 / @mrbatista) +- dashboard: fix duplicate plugin IDs, see #702 (@goto-bus-stop) +- dashboard/statusbar: fix some unicode characters showing up as gibberish (#787 / @goto-bus-stop) +- dashboard: Fix grid item height in remote providers with few files (#791 / @goto-bus-stop) +- dashboard: Add `rel="noopener noreferrer"` to links containing `target="_blank"` (#767 / @kvz) +- instagram: add extensions to instagram files (@ifedapoolarewaju) +- transloadit: More robust failure handling for Transloadit, closes #708 (#805 / @goto-bus-stop) +- docs: Document "headers" upload parameter in AwsS3 plugin (#780 / @janko-m) +- docs: Update some `uppy.state` docs to align with the Stores feature (#792 / @goto-bus-stop) +- dragdrop: Add `inputName` option like FileInput has, set empty value="", closes #729 (#778 / @goto-bus-stop, @arturi) +- docs: Google Cloud Storage setup for the AwsS3 plugin (#777 / goto-bus-stop) +- react: Update React component PropTypes (#776 / @arturi) +- statusbar: add some spacing between text elements (#760 / @goto-bus-stop) ## 0.24.2 @@ -168,6 +206,14 @@ Released: 2018-04-12. - url: Add checks for protocols, assume `http` when no protocol is used (#682 / @arturi) - url: Refactor things into Provider, see comments in https://github.com/transloadit/uppy/pull/588; exposing the Provider module and the ProviderView to the public API (#727 / @ifedapoolarewaju, @arturi) - webcam: Styles updates: adapt for mobile, better camera icon, move buttons to the bottom bar (#682 / @arturi) +- server: Fixed security vulnerability in transient dependency [#70](https://github.com/transloadit/uppy-server/issues/70) (@ifedapoolarewaju) +- server: Auto-generate tmp download file name to avoid Path traversal (@ifedapoolarewaju) +- server: Namespace redis key storage/lookup to avoid collisions (@ifedapoolarewaju) +- server: Validate callback redirect url after completing OAuth (@ifedapoolarewaju) +- server: Reduce the permission level required by Google Drive (@ifedapoolarewaju) +- server: Auto-generate Server secret if none is provided on startup (@ifedapoolarewaju) +- server: We implemented a more standard logger for Uppy Server (@ifedapoolarewaju) +- server: Added an example project to run Uppy Server on Serverless (@ifedapoolarewaju) ## 0.23.3 diff --git a/README.md b/README.md index 9ce748902..93fe5cea0 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ $ npm install uppy --save We recommend installing from npm and then using a module bundler such as [Webpack](http://webpack.github.io/), [Browserify](http://browserify.org/) or [Rollup.js](http://rollupjs.org/). -Add CSS [uppy.min.css](https://transloadit.edgly.net/releases/uppy/v0.24.2/dist/uppy.min.css), either to `` of your HTML page or include in JS, if your bundler of choice supports it — transforms and plugins are available for Browserify and Webpack. +Add CSS [uppy.min.css](https://transloadit.edgly.net/releases/uppy/v0.24.4/dist/uppy.min.css), either to `` of your HTML page or include in JS, if your bundler of choice supports it — transforms and plugins are available for Browserify and Webpack. Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly. In that case `Uppy` will attach itself to the global `window.Uppy` object. @@ -72,12 +72,12 @@ Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly 1\. Add a script to the bottom of ``: ``` html - + ``` 2\. Add CSS to ``: ``` html - + ``` 3\. Initialize: diff --git a/bin/upload-to-cdn.sh b/bin/upload-to-cdn.sh index 56f5ecbd7..d9b71ac36 100755 --- a/bin/upload-to-cdn.sh +++ b/bin/upload-to-cdn.sh @@ -8,7 +8,7 @@ # - Checks if a tag is being built (on Travis - otherwise opts to continue execution regardless) # - Installs AWS CLI if needed # - Assumed a fully built uppy is in root dir (unless a specific tag was specified, then it's fetched from npm) -# - Runs npm pack, and stores files to e.g. https://transloadit.edgly.net/releases/uppy/v0.24.2/dist/uppy.css +# - Runs npm pack, and stores files to e.g. https://transloadit.edgly.net/releases/uppy/v0.24.4/dist/uppy.css # - Uses local package by default, if [version] argument was specified, takes package from npm # # Run as: diff --git a/examples/cdn-example/index.html b/examples/cdn-example/index.html index ddf500a62..ff0ccda8c 100644 --- a/examples/cdn-example/index.html +++ b/examples/cdn-example/index.html @@ -4,11 +4,11 @@ - + - + + + ``` 2\. Add CSS to ``: ``` html - + ``` 3\. Initialize: diff --git a/website/src/docs/transloadit.md b/website/src/docs/transloadit.md index 631b2f29d..5d561cbee 100644 --- a/website/src/docs/transloadit.md +++ b/website/src/docs/transloadit.md @@ -24,6 +24,29 @@ uppy.use(Transloadit, { As of Uppy 0.24 the Transloadit plugin includes the [Tus](/docs/tus) plugin to handle the uploading, so you no longer have to add it manually. +## Properties + +### `Transloadit.UPPY_SERVER` + +The main endpoint for Transloadit's hosted uppy-servers. You can use this constant in remote provider options, like so: + +```js +const Dropbox = require('uppy/lib/plugins/Dropbox') +const Transloadit = require('uppy/lib/plugins/Transloadit') + +uppy.use(Dropbox, { + host: Transloadit.UPPY_SERVER +}) +``` + +The value of this constant is `https://api2.transloadit.com/uppy-server`. If you are using a custom [`service`](#service) option, you should also set a custom host option in your provider plugins, by taking a Transloadit API url and appending `/uppy-server`: + +```js +uppy.use(Dropbox, { + host: 'https://api2-us-east-1.transloadit.com/uppy-server' +}) +``` + ## Options ### `service` diff --git a/website/src/docs/tus.md b/website/src/docs/tus.md index 5aacc82c2..259fcab95 100644 --- a/website/src/docs/tus.md +++ b/website/src/docs/tus.md @@ -36,4 +36,8 @@ URL to upload to, where your tus.io server is running. Whether to auto-retry the upload when the user's internet connection is back online after an outage. +### `limit: 0` + +Limit the amount of uploads going on at the same time. Passing `0` means no limit. + [tus-js-client]: https://github.com/tus/tus-js-client diff --git a/website/src/docs/uppy.md b/website/src/docs/uppy.md index d2d18dd12..270359f4c 100644 --- a/website/src/docs/uppy.md +++ b/website/src/docs/uppy.md @@ -15,10 +15,10 @@ const uppy = Uppy({ autoProceed: true, debug: false, restrictions: { - maxFileSize: false, - maxNumberOfFiles: false, - minNumberOfFiles: false, - allowedFileTypes: false + maxFileSize: null, + maxNumberOfFiles: null, + minNumberOfFiles: null, + allowedFileTypes: null }, meta: {}, onBeforeFileAdded: (currentFile, files) => currentFile, @@ -52,10 +52,14 @@ Optionally provide rules and conditions for which files can be selected. **Parameters** -- `maxFileSize` *number* -- `maxNumberOfFiles` *number* -- `minNumberOfFiles` *number* -- `allowedFileTypes` *array* of wildcards or exact mime types, like `image/*` +- `maxFileSize` *null | number* +- `maxNumberOfFiles` *null | number* +- `minNumberOfFiles` *null | number* +- `allowedFileTypes` *null | array* of wildcards `image/*`, exact mime types `image/jpeg`, or file extensions `.jpg`: `['image/*', '.jpg', '.jpeg', '.png', '.gif']` + +`maxNumberOfFiles` affects the number of files user is able to select via the system file dialog in UI plugins like `DragDrop`, `FileInput` and `Dashboard`: when set to `1` they will only be able to select a single file, otherwise, when `null` or other number, they will be able to select multiple files. + +`allowedFileTypes` gets passed to the system file dialog via [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Limiting_accepted_file_types)’s accept attribute, so only files matching these types will be selectable. ### `meta: {}` @@ -69,7 +73,7 @@ meta: { This global metadata is added to each file in Uppy. It can be modified with two methods: -1. [`uppy.setMeta({ username: 'Peter' })`](/docs/uppy/#uppy-setmeta-data) — set or update meta for all files. +1. [`uppy.setMeta({ username: 'Peter' })`](/docs/uppy/#uppy-setMeta-data) — set or update meta for all files. 2. [`uppy.setFileMeta('myfileID', { resize: 1500 })`](/docs/uppy/#uppy-setFileMeta-fileID-data) — set or update meta for specific file. Metadata from each file is then attached to uploads in [Tus](/docs/tus/) and [XHRUpload](/docs/xhrupload/) plugins. @@ -192,9 +196,9 @@ We are using a forked [Polyglot.js](https://github.com/airbnb/polyglot.js/blob/m ### `store: defaultStore()` -The Store to use to keep track of internal state. By default, a simple object is used. +The Store to use to keep track of internal state. By [default](/docs/stores/#DefaultStore), a simple object is used. -This option can be used to plug Uppy state into an external state management library, such as Redux. Then, you can write custom views with the library that is also used by the rest of the application. +This option can be used to plug Uppy state into an external state management library, such as [Redux](/docs/stores/#ReduxStore). Then, you can write custom views with the library that is also used by the rest of the application. @@ -236,7 +240,7 @@ If `uppy.opts.autoProceed === true`, Uppy will begin uploading automatically whe ### `uppy.getFile(fileID)` -A shortcut method that returns a specific file object from `uppy.state` by its `fileID`. +Get a specific file object by its ID. ```js const file = uppy.getFile('uppyteamkongjpg1501851828779') @@ -286,7 +290,7 @@ uppy.upload().then((result) => { ### `uppy.setState(patch)` -Update `uppy.state`. Usually this method is called internally, but in some cases it might be useful to alter something in `uppy.state` directly. +Update Uppy's internal state. Usually this method is called internally, but in some cases it might be useful to alter something directly, especially when implementing your own plugins. Uppy’s default state on initialization: @@ -316,18 +320,18 @@ uppy.setState({ }) ``` -We don’t mutate `uppy.state`, so internally `setState` creates a new copy of state and replaces `uppy.state` with it. However, when updating values, it’s your responsibility to not mutate them, but instead create copies. See [Redux docs](http://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html) for more info on this. Here’s an example from Uppy.Core that updates progress for a particular file in state: +State in Uppy is considered to be immutable. When updating values, it’s your responsibility to not mutate them, but instead create copies. See [Redux docs](http://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html) for more info on this. Here’s an example from Uppy.Core that updates progress for a particular file in state: ```js +// We use Object.assign({}, obj) to create a copy of `obj`. const updatedFiles = Object.assign({}, uppy.getState().files) -const updatedFile = Object.assign({}, updatedFiles[fileID], - Object.assign({}, { - progress: Object.assign({}, updatedFiles[fileID].progress, { - bytesUploaded: data.bytesUploaded, - bytesTotal: data.bytesTotal, - percentage: Math.floor((data.bytesUploaded / data.bytesTotal * 100).toFixed(2)) - }) - } +// We use Object.assign({}, obj, update) to create an altered copy of `obj`. +const updatedFile = Object.assign({}, updatedFiles[fileID], { + progress: Object.assign({}, updatedFiles[fileID].progress, { + bytesUploaded: data.bytesUploaded, + bytesTotal: data.bytesTotal, + percentage: Math.floor((data.bytesUploaded / data.bytesTotal * 100).toFixed(2)) + }) )) updatedFiles[data.id] = updatedFile uppy.setState({files: updatedFiles}) @@ -335,7 +339,7 @@ uppy.setState({files: updatedFiles}) ### `uppy.getState()` -Returns `uppy.state`, which you can also use directly. +Returns the current state from the [Store](#store-defaultStore). ### `uppy.setFileState(fileID, state)` @@ -487,7 +491,7 @@ uppy.on('complete', (result) => { ### `error` -Fired when Uppy fails to upload/encode the whole upload. That error is then set to `uppy.state.error`. +Fired when Uppy fails to upload/encode the whole upload. That error is then set to `uppy.getState().error`. ### `upload-error` diff --git a/website/src/docs/webcam.md b/website/src/docs/webcam.md index 12e6c675d..b6b1a05d7 100644 --- a/website/src/docs/webcam.md +++ b/website/src/docs/webcam.md @@ -7,6 +7,8 @@ permalink: docs/webcam/ The Webcam plugin lets you take photos and record videos with a built-in camera on desktop and mobile devices. +> To use the Webcam plugin in Chrome, [your site should be served over https](https://developers.google.com/web/updates/2015/10/chrome-47-webrtc#public_service_announcements). This restriction does not apply on `localhost`, so you don't have to jump through many hoops during development. + [Try live!](/examples/dashboard/) ## Options diff --git a/website/src/docs/xhrupload.md b/website/src/docs/xhrupload.md index e839cba44..0181b84eb 100644 --- a/website/src/docs/xhrupload.md +++ b/website/src/docs/xhrupload.md @@ -183,9 +183,12 @@ The default form field for file uploads is `files[]`, which means you have to ac // upload.php $files = $_FILES['files']; $file_path = $files['tmp_name'][0]; // temporary upload path of the first file -move_uploaded_file($file_path, './img/img.png'); // save the file at `img/img.png` +$file_name = $_POST['name']; // desired name of the file +move_uploaded_file($file_path, './img/' . basename($file_name)); // save the file in `img/` ``` +Note how we're using `$_POST['name']` instead of `$my_file['name']`. `$my_file['name']` contains the original name of the file on the user's device. `$_POST['name']` contains the `name` metadata value for the uploaded file, which can be edited by the user using the [Dashboard](/docs/dashboard). + Set a custom `fieldName` to make working with the `$_FILES` array a bit less convoluted: ```js @@ -201,7 +204,7 @@ uppy.use(XHRUpload, { // upload.php $my_file = $_FILES['my_file']; $file_path = $my_file['tmp_name']; // temporary upload path of the file -$file_name = $my_file['name']; // original name of the file +$file_name = $_POST['name']; // desired name of the file move_uploaded_file($file_path, './img/' . basename($file_name)); // save the file at `img/FILE_NAME` ``` diff --git a/website/src/examples/i18n/app.html b/website/src/examples/i18n/app.html index 2a29e3c12..170070878 100644 --- a/website/src/examples/i18n/app.html +++ b/website/src/examples/i18n/app.html @@ -1,11 +1,11 @@ - +
- + + +