Skip to content

Latest commit

 

History

History
888 lines (870 loc) · 23.1 KB

constructor.md

File metadata and controls

888 lines (870 loc) · 23.1 KB
new FilesCollection([config]) [Isomorphic]

Initialize FilesCollection collection.

Param/Type Locus Description Default Comment
config {Object} Isomorphic [Optional] {} See all options below
config.storagePath {String|Function} Server Storage path on file system function { return 'assets/app/uploads'; }
Always converted into the function since v1.7.4
Relative to running script
If Function is passed it must return String, arguments:
  • defaultPath - Default recommended path
Context is current FilesCollction instance.

Note: When running in development mode files stored at a relative path (within the Meteor project) are silently removed when Meteor is restarted.

To preserve files in development mode store them outside of the Meteor application, e.g. /data/Meteor/uploads/

The Meteor-Files package operates on the host filesystem, unlike Meteor Assets. When a relative path is specified for config.storagePath (path starts with ./ or no slash) files will be located relative to the assets folder.

When an absolute path is used (path starts with /) files will be located starting at the root of the filesystem.

If using MeteorUp, Docker volumes has to be created in mup.json, see Usage on MeteorUp
config.collection {Mongo.Collection} Isomorphic Mongo.Collection Instance You can pass your own Mongo Collection instance {collection: new Mongo.Collection('myFiles')}
config.collectionName {String} Isomorphic Collection name MeteorUploadFiles
config.continueUploadTTL {String} Server Time in seconds, during upload may be continued, default 3 hours (10800 seconds) 10800 (3 hours) If upload is not continued during this time, memory used for this upload will be freed. And uploaded chunks is removed. Server will no longer wait for upload, and if upload will be tied to be continued - Server will return 408 Error (Can't continue upload, session expired. Start upload again.)
config.ddp {Object} Client Custom DDP connection for Collection. Object returned form DDP.connect() Meteor (The default DDP connection)
config.cacheControl {String} Server Set Cache-Control header public, max-age=31536000, s-maxage=31536000
config.responseHeaders {Object|Function} Server Allows to change default response headers Default Function We recommend to keep original function structure, with your modifications, see example altering default headers
config.throttle {Number|false} Server Throttle download speed in bps false
config.downloadRoute {String} Isomorphic Server Route used to retrieve files /cdn/storage
config.schema {Object} Isomorphic Collection Schema Default Schema For more info read Schema docs
config.chunkSize {Number} Isomorphic Upload & Serve (for 206 responce) chunk size 272144
config.namingFunction {Function} Isomorphic Function which returns String false Primary sets file name on FS
if namingFunction is not set
FS-name is equal to file's record _id
config.permissions {Number} Server FS-permissions (access rights) in octal 0644 ex.: 0755, 0777
config.parentDirPermissions {Number} Server FS-permissions for parent directory (access rights) in octal 0755 ex.: 0777
config.integrityCheck {Boolean} Server CRC file check true
config.strict {Boolean} Server Strict mode for partial content false If is true server will return 416 response code, when range is not specified
config.downloadCallback {Function} Server Called right before initiate file download.
Arguments:
Context:
  • this.request
  • this.response
  • this.user()
  • this.userId
false Function should return {Boolean} value, return false to abort download, and true to continue
config.protected {Boolean|Function} Isomorphic Control download flow.
If function:
Arguments:
  • fileObj {Object|null} - If requested file exists - file object, otherwise - null

Context:
  • this.request - On server only
  • this.response - On server only
  • this.user()
  • this.userId
false If true - files will be served only to authorized users, if function() - you're able to check visitor's permissions in your own way.
  • return true to continue
  • return false to abort or {Number} to abort upload with specific response code, default response code is 401
config.public {Boolean} Isomorphic Allows to place files in public directory of your web-server. And let your web-server to serve uploaded files false Important notes:
  • Collection can not be public and protected at the same time!
  • downloadRoute must be explicitly provided. And pointed to root of web/proxy-server, like /uploads/
  • storagePath must point to absolute root path of web/proxy-server, like '/var/www/myapp/public/uploads/'
  • integrityCheck is not guaranteed!
  • play and force download features is not guaranteed!
  • Remember: NodeJS is not best solution for serving files
config.onBeforeUpload {Function} Isomorphic Callback, triggered right before upload is started on client and right after receiving a chunk on server
Arguments:
  • fileData {Object} - Current file metadata

Context:
  • this.file
  • this.user()
  • this.userId
  • this.chunkId {Number} - On server only
  • this.eof {Boolean} - On server only
false
  • return true to continue
  • return false to abort or {String} to abort upload with message

note: Because sending meta data as part of every chunk would hit the performance, meta is always empty ({}) except on the first chunk (chunkId=1 or chunkId=-1) and on eof (eof=true or chunkId=-1) (Fixed. Since v1.6.0 full file object is available in onBeforeUpload callback)

config.onInitiateUpload {Function} Server Function which executes on server right before upload is begin and right after onBeforeUpload hook returns true. This hook called only once per upload and fully asynchronous.
Arguments:
  • fileData {Object} - Current file metadata

Context:
  • this.file
  • this.user()
  • this.userId
  • this.chunkId {Number} - On server only
false See: #208
config.onBeforeRemove {Function} Server Callback, triggered right before remove file
Arguments:
  • cursor {MongoCursor} - Current files to be removed on cursor, if has any

Context:
  • this.user()
  • this.userId
false Use with allowClientCode to control access to remove() method.
  • return true to continue
  • return false to abort
config.onAfterUpload {Function} Server Callback, triggered after file is written to FS
Arguments:
  • fileRef {Object} - Record from MongoDB
false Alternatively use: addListener('afterUpload', func)
config.onAfterRemove {Function} Server Callback, triggered after file(s) is removed from Collection
Arguments:
  • files {[Object]} - Array of removed documents
false
config.onbeforeunloadMessage {String|Function} Client Message shown to user when closing browser's window or tab, while upload in the progress Upload in a progress... Do you want to abort?
config.allowClientCode {Boolean} Isomorphic Allow use remove() method on client true
config.debug {Boolean} Isomorphic Turn on/of debugging and extra logging false
config.interceptDownload {Function} Server Intercept download request.
Arguments:
  • http {Object} - Middleware request instance
  • http.request {Object} - example: http.request.headers
  • http.response {Object} - example: http.response.end()
  • fileRef {Object} - Current file record from MongoDB
  • version {String} - Requested file version
false Usage example: Serve file from third-party resource.
  • return false from this function to continue standard behavior
  • return true to intercept incoming request

Event map:

Name Locus Description Comment
afterUpload Isomorphic Triggered right after file is written to FS.
Arguments:
  • fileRef {Object} - Record from MongoDB

Examples:

var Images;
Images = new FilesCollection({
  storagePath: 'assets/app/uploads/Images',
  downloadRoute: '/files/images'
  collectionName: 'Images',
  chunkSize: 1024*2048,
  throttle: 1024*512,
  permissions: 0755,
  allowClientCode: false,
  cacheControl: 'public, max-age=31536000',
  onbeforeunloadMessage: function () {
    return 'Upload is still in progress! Upload will be aborted if you leave this page!';
  },
  onBeforeUpload: function (file) {
    // Allow upload files under 10MB, and only in png/jpg/jpeg formats
    if (file.size <= 10485760 && /png|jpg|jpeg/i.test(file.ext)) {
      return true;
    } else {
      return 'Please upload image, with size equal or less than 10MB';
    }
  },
  downloadCallback: function (fileObj) {
    if (this.params.query.download == 'true') {
      // Increment downloads counter
      Images.update(fileObj._id, {$inc: {'meta.downloads': 1}});
    }
    // Must return true to continue download
    return true;
  },
  protected: function (fileObj) {
    // Check if user is own this file
    if (fileObj.meta.owner === this.userId) {
      return true;
    } else {
      return false;
    }
  }
});

Add extra security:

Attach schema [Isomorphic]:

Default schema is stored under FilesCollection.schema object.

To attach schema, use/install aldeed:collection2 and simple-schema packages.

You're free to modify/overwrite FilesCollection.schema object.

var Images = new FilesCollection({/* ... */});
Images.collection.attachSchema(new SimpleSchema(Images.schema));

Deny collection interaction on client [Server]:

Deny insert/update/remove from client

if (Meteor.isServer) {
  var Images = new FilesCollection({/* ... */});
  Images.deny({
    insert: function() {
      return true;
    },
    update: function() {
      return true;
    },
    remove: function() {
      return true;
    }
  });

  /* Equal shortcut: */
  Images.denyClient();
}

Allow collection interaction on client [Server]:

Allow insert/update/remove from client

if (Meteor.isServer) {
  var Images = new FilesCollection({/* ... */});
  Images.allow({
    insert: function() {
      return true;
    },
    update: function() {
      return true;
    },
    remove: function() {
      return true;
    }
  });

  /* Equal shortcut: */
  Images.allowClient();
}

Events listeners:

var Images = new FilesCollection({/* ... */});
// Alias addListener
Images.on('afterUpload', function (fileRef) {
  /* ... */
});

Use onBeforeUpload to avoid unauthorized upload:

var Images = new FilesCollection({
  collectionName: 'Images',
  allowClientCode: true,
  onBeforeUpload: function () {
    if (this.userId) {
      var user = this.user();
      if (user.profile.role === 'admin') {
        // Allow upload only if
        // current user is signed-in
        // and has role is `admin`
        return true;
      }
    }

    return "Not enough rights to upload a file!";
  }
});

Use onBeforeRemove to avoid unauthorized remove:

For more info see remove method.

var Images = new FilesCollection({
  collectionName: 'Images',
  allowClientCode: true,
  onBeforeRemove: function () {
    if (this.userId) {
      var user = this.user();
      if (user.profile.role === 'admin') {
        // Allow removal only if
        // current user is signed-in
        // and has role is `admin`
        return true;
      }
    }

    return false;
  }
});