Repository navigation
v4.0.0: secure defaults, storage adapters, signed links, resumable uploads - #921
Draft
dr-dimitru wants to merge 45 commits into
Draft
dr-dimitru wants to merge 45 commits into
dr-dimitru wants to merge 45 commits into
Conversation
The puppeteer driver in meteortesting:browser-tests resolves its module through Meteor's Npm.require, which never looks at NODE_PATH or this repo's node_modules under test-packages. The playwright driver imports from $PWD/node_modules, so it works without a test app.
BREAKING CHANGE: FilesCursor#hasNext() and FilesCursor#countAsync() are gone. Use hasNextAsync() and countDocuments().
…ookup BREAKING CHANGE: FilesCollectionCore no longer has findOne(). The client class has it, the server class throws Meteor.Error(404) as before. Meteor.server.sessions must be a Map (Meteor 3), a plain object now throws.
BREAKING CHANGE: the first pipe() call now runs first. Reverse the order of chained pipe() calls written for v3.
BREAKING CHANGE: client remove() and removeAsync() take a String _id. Use find(selector).removeAsync() to remove several files.
BREAKING CHANGE: clients can no longer call remove() unless allowClientCode: true is set on the server and the client. Set onBeforeRemove when you enable it.
BREAKING CHANGE: file responses carry X-Content-Type-Options: nosniff. Set nosniff: false to turn it off.
BREAKING CHANGE: only image/* (not SVG), video/*, audio/*, application/pdf, and text/plain are served inline. Set Content-Disposition in responseHeaders to change it.
BREAKING CHANGE: the client namingFunction option and the FSName field are ignored. Set namingFunction on the server. It receives { file, fileId, userId } in upload Start, writeAsync(), and loadAsync().
… file BREAKING CHANGE: other keys of the client file object are dropped. Send custom data in meta.
BREAKING CHANGE: type, mime, versions.original.type, and the is* flags come from the file content. Set trustClientMimeType: true to store the uploader's type as in 3.x.
…types A UTF-8 file labeled text/html, text/xml, text/css, or text/javascript was stored with that type, so a browser could run it. Only text/plain, text/csv, text/markdown, text/tab-separated-values, text/calendar, text/vtt, and application/json are kept, anything else becomes text/plain. Client types ending in +xml no longer refine a zip or CFB container.
…er on invalid tokens
…apter
BREAKING CHANGE: serve() is async and returns a Promise; await it when code runs after it. unlinkAsync() and removeAsync() remove files through the storage adapter (FSStorage by default, same files as before). Custom adapters receive { source } as the 4th put() argument and must keep the caller's file when source is 'addFile'.
…he built-in GridFS adapter
…tart The server guessed written chunks from the file size after a restart, so a hole before the last written chunk passed as complete. BREAKING CHANGE: uploads started before 4.0 get 410 on their next chunk and must restart. Start rejects more than 100000 chunks with 400; the client raises chunkSize to stay below.
.versions also moves base64 from 1.0.14 to 1.0.16, the version Meteor 3.5.2 resolves in a throwaway app.
The docs share one secret across collections, and clients choose upload file ids, so a token for an `_id` in one collection also opened the same `_id` in another collection. The token string format stays the same.
The default `public, max-age=31536000` let a CDN keep a token response for a year, so anyone with the URL could fetch the file after the token expired. Token downloads now get `private, max-age=<seconds until exp>` unless `responseHeaders` sets `Cache-Control`.
When a resumed upload finished on another process, the observer on this process called `end()`. Its stream lacked the other process's chunks, so it waited 25 seconds, aborted, and unlinked the finished file. The observer now only closes the file handle.
…adapters server only
…lient in shared examples
…ype changelog entry
…lections A shared cache in front of the app could keep a protected file and serve it to other users. BREAKING CHANGE: protected collections now send `Cache-Control: private, max-age=31536000` by default. Set `cacheControl` to restore `public, max-age=31536000, s-maxage=31536000`.
Thanks to @ToyboxZach (#861), @xet7 (#862), @dhana-exe (#799), @jankapunkt (#753), @ThaumRystra (#874), @sylido (#505), @codeonprod (#908), and @jankapunkt (#906) for reporting and discussing these issues.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FilesCursor#hasNext,FilesCursor#countAsync, the serverfindOneshim, and the plain-object session lookup._idin_Remove; client cursor removal sends one call per file.allowClientCodetofalseandnosnifftotrue.Cache-Control: privateby default for protected collections.attachmentunless the type is safe to show inline.name,type,size, andmetafrom the client file.trustClientMimeTypeoption keeps the 3.x behavior.storageoption, built-inFSStorageandGridFSStorage);serve()is async.downloadTokenSecret,createDownloadToken(),link(..., { token }).protected: truein favor of a function that checks ownership.docs/migration-to-v4.mdand the 4.0.0 changelog.Verification
npm run lintandnpm run typecheck: pass.npm run test:mochaon Meteor 3.5.2 and 3.2.2: 403 passing.npm run test:browseron Meteor 3.5.2 and 3.2.2: 403 server and 19 client tests passing.Migration
Breaking changes and an upgrade checklist are in
docs/migration-to-v4.md.Issues
Closes #908, closes #906, closes #874, closes #861, closes #862, closes #799, closes #753, closes #505.
Thanks to @codeonprod, @jankapunkt, @ThaumRystra, @ToyboxZach, @xet7, @dhana-exe, and @sylido for reporting them.