diff --git a/.versions b/.versions index 8a66b95..55ebfad 100644 --- a/.versions +++ b/.versions @@ -21,7 +21,7 @@ fetch@0.1.1 geojson-utils@1.0.10 id-map@1.1.1 inter-process-messaging@0.1.1 -local-test:ostrio:files@2.2.1 +local-test:ostrio:files@2.3.0 logging@1.3.1 meteor@1.10.0 minimongo@1.8.0 @@ -35,7 +35,7 @@ mongo-id@1.0.8 npm-mongo@4.3.1 ordered-dict@1.1.0 ostrio:cookies@2.7.2 -ostrio:files@2.2.1 +ostrio:files@2.3.0 promise@0.12.0 random@1.2.0 react-fast-refresh@0.2.3 diff --git a/client.js b/client.js index 8514f5b..111c058 100644 --- a/client.js +++ b/client.js @@ -8,9 +8,9 @@ import FilesCollectionCore from './core.js'; import { formatFleURL, helpers } from './lib.js'; const NOOP = () => { }; -const allowedParams = ['debug', 'ddp', 'schema', 'public', 'chunkSize', 'downloadRoute', 'collection', 'collectionName', 'namingFunction', 'onBeforeUpload', 'allowClientCode', 'onbeforeunloadMessage', 'disableUpload', 'disableSetTokenCookie', 'allowQueryStringCookies']; +const allowedParams = ['allowClientCode', 'allowQueryStringCookies', 'chunkSize', 'collection', 'collectionName', 'ddp', 'debug', 'disableSetTokenCookie', 'disableUpload', 'downloadRoute', 'namingFunction', 'onBeforeUpload', 'onbeforeunloadMessage', 'public', 'sanitize', 'schema']; -/* +/** * @locus Anywhere * @class FilesCollection * @param config {Object} - [Both] Configuration object with next properties: @@ -31,6 +31,7 @@ const allowedParams = ['debug', 'ddp', 'schema', 'public', 'chunkSize', 'downloa * @param config.disableUpload {Boolean} - Disable file upload, useful for server only solutions * @param config.disableSetTokenCookie {Boolean} - Disable cookie setting. Useful when you use multiple file collections or when you want to implement your own authorization. * @param config.allowQueryStringCookies {Boolean} - Allow passing Cookies in a query string (in URL). Primary should be used only in Cordova environment. Note: this option will be used only on Cordova. Default: `false` + * @param config.sanitize {Function} - Override default sanitize function * @summary Create new instance of FilesCollection */ class FilesCollection extends FilesCollectionCore { @@ -173,7 +174,7 @@ class FilesCollection extends FilesCollectionCore { }; } - /* + /** * @locus Anywhere * @memberOf FilesCollection * @name _getMimeType @@ -194,7 +195,7 @@ class FilesCollection extends FilesCollectionCore { return mime; } - /* + /** * @locus Anywhere * @memberOf FilesCollection * @name _getUser @@ -217,7 +218,7 @@ class FilesCollection extends FilesCollectionCore { return result; } - /* + /** * @locus Client * @memberOf FilesCollection * @name insert @@ -251,13 +252,13 @@ class FilesCollection extends FilesCollectionCore { */ insert(config, autoStart = true) { if (this.disableUpload) { - console.warn('[FilesCollection] [insert()] Upload is disabled with [disableUpload]!'); + Meteor._debug('[FilesCollection] [insert()] Upload is disabled with [disableUpload]!'); return {}; } return (new UploadInstance(config, this))[autoStart ? 'start' : 'manual'](); } - /* + /** * @locus Anywhere * @memberOf FilesCollection * @name remove diff --git a/docs/constructor.md b/docs/constructor.md index 3122132..8446e9d 100644 --- a/docs/constructor.md +++ b/docs/constructor.md @@ -873,6 +873,23 @@ Useful when you use multiple file collections or when you want to implement your own authorization. +
config.sanitize
{Function}
+ sanitize()
method of FilesCollection instance. Primary used for FSName
and fileId
. Very low-level. Warning: use with caution!
+ config._preCollection
{Mongo.Collection}
diff --git a/package.js b/package.js
index a32abfe..9d52290 100755
--- a/package.js
+++ b/package.js
@@ -1,6 +1,6 @@
Package.describe({
name: 'ostrio:files',
- version: '2.2.1',
+ version: '2.3.0',
summary: 'Upload files to a server or 3rd party storage: AWS:S3, GridFS, DropBox, and other',
git: 'https://github.com/veliovgroup/Meteor-Files',
documentation: 'README.md'
diff --git a/server.js b/server.js
index bf11de6..30dd9b2 100644
--- a/server.js
+++ b/server.js
@@ -111,6 +111,7 @@ const createIndex = async (collection, keys, opts) => {
* @param config.disableDownload {Boolean} - Disable file download (serving), useful for file management only solutions
* @param config.allowedOrigins {Regex|Boolean} - [Server] Regex of Origins that are allowed CORS access or `false` to disable completely. Defaults to `/^http:\/\/localhost:12[0-9]{3}$/` for allowing Meteor-Cordova builds access
* @param config.allowQueryStringCookies {Boolean} - Allow passing Cookies in a query string (in URL). Primary should be used only in Cordova environment. Note: this option will be used only on Cordova. Default: `false`
+ * @param config.sanitize {Function} - Override default sanitize function
* @param config._preCollection {Mongo.Collection} - [Server] Mongo preCollection Instance
* @param config._preCollectionName {String} - [Server] preCollection name
* @summary Create new instance of FilesCollection
@@ -121,39 +122,40 @@ class FilesCollection extends FilesCollectionCore {
let storagePath;
if (config) {
({
- storagePath,
- debug: this.debug,
- schema: this.schema,
- public: this.public,
- strict: this.strict,
- getUser: this.getUser,
+ _preCollection: this._preCollection,
+ _preCollectionName: this._preCollectionName,
+ allowClientCode: this.allowClientCode,
+ allowedOrigins: this.allowedOrigins,
+ allowQueryStringCookies: this.allowQueryStringCookies,
+ cacheControl: this.cacheControl,
chunkSize: this.chunkSize,
- protected: this.protected,
collection: this.collection,
- permissions: this.permissions,
- cacheControl: this.cacheControl,
+ collectionName: this.collectionName,
+ continueUploadTTL: this.continueUploadTTL,
+ debug: this.debug,
+ disableDownload: this.disableDownload,
+ disableUpload: this.disableUpload,
+ downloadCallback: this.downloadCallback,
downloadRoute: this.downloadRoute,
- onAfterUpload: this.onAfterUpload,
+ getUser: this.getUser,
+ integrityCheck: this.integrityCheck,
+ interceptDownload: this.interceptDownload,
+ interceptRequest: this.interceptRequest,
+ namingFunction: this.namingFunction,
onAfterRemove: this.onAfterRemove,
- disableUpload: this.disableUpload,
+ onAfterUpload: this.onAfterUpload,
onBeforeRemove: this.onBeforeRemove,
- integrityCheck: this.integrityCheck,
- collectionName: this.collectionName,
onBeforeUpload: this.onBeforeUpload,
- namingFunction: this.namingFunction,
- responseHeaders: this.responseHeaders,
- disableDownload: this.disableDownload,
- allowedOrigins: this.allowedOrigins,
- allowClientCode: this.allowClientCode,
- downloadCallback: this.downloadCallback,
onInitiateUpload: this.onInitiateUpload,
- interceptRequest: this.interceptRequest,
- interceptDownload: this.interceptDownload,
- continueUploadTTL: this.continueUploadTTL,
parentDirPermissions: this.parentDirPermissions,
- allowQueryStringCookies: this.allowQueryStringCookies,
- _preCollection: this._preCollection,
- _preCollectionName: this._preCollectionName,
+ permissions: this.permissions,
+ protected: this.protected,
+ public: this.public,
+ responseHeaders: this.responseHeaders,
+ sanitize: this.sanitize,
+ schema: this.schema,
+ storagePath,
+ strict: this.strict,
} = config);
}
@@ -288,6 +290,10 @@ class FilesCollection extends FilesCollectionCore {
this.continueUploadTTL = 10800;
}
+ if (!helpers.isFunction(this.sanitize)) {
+ this.sanitize = helpers.sanitize;
+ }
+
if (!helpers.isFunction(this.responseHeaders)) {
this.responseHeaders = (responseCode, fileRef, versionRef) => {
const headers = {};
@@ -571,7 +577,7 @@ class FilesCollection extends FilesCollectionCore {
if (httpReq.headers['x-start'] !== '1') {
// CHUNK UPLOAD SCENARIO:
opts = {
- fileId: helpers.sanitize(httpReq.headers['x-fileid'], 20, 'a')
+ fileId: this.sanitize(httpReq.headers['x-fileid'], 20, 'a')
};
if (httpReq.headers['x-eof'] === '1') {
@@ -647,7 +653,7 @@ class FilesCollection extends FilesCollectionCore {
}
if (opts.fileId) {
- opts.fileId = helpers.sanitize(opts.fileId, 20, 'a');
+ opts.fileId = this.sanitize(opts.fileId, 20, 'a');
}
this._debug(`[FilesCollection] [File Start HTTP] ${opts.file.name || '[no-name]'} - ${opts.fileId}`);
@@ -842,7 +848,7 @@ class FilesCollection extends FilesCollectionCore {
check(returnMeta, Match.Optional(Boolean));
- opts.fileId = helpers.sanitize(opts.fileId, 20, 'a');
+ opts.fileId = self.sanitize(opts.fileId, 20, 'a');
self._debug(`[FilesCollection] [File Start Method] ${opts.file.name} - ${opts.fileId}`);
opts.___s = true;
@@ -886,7 +892,7 @@ class FilesCollection extends FilesCollectionCore {
chunkId: Match.Optional(Number)
});
- opts.fileId = helpers.sanitize(opts.fileId, 20, 'a');
+ opts.fileId = self.sanitize(opts.fileId, 20, 'a');
if (opts.binData) {
opts.binData = Buffer.from(opts.binData, 'base64');
@@ -984,7 +990,7 @@ class FilesCollection extends FilesCollectionCore {
result.ext = extension;
result._id = opts.fileId;
result.userId = userId || null;
- opts.FSName = helpers.sanitize(opts.FSName);
+ opts.FSName = this.sanitize(opts.FSName);
if (this.namingFunction) {
opts.FSName = this.namingFunction(opts);
@@ -1225,7 +1231,7 @@ class FilesCollection extends FilesCollectionCore {
check(callback, Match.Optional(Function));
check(proceedAfterUpload, Match.Optional(Boolean));
- opts.fileId = opts.fileId && helpers.sanitize(opts.fileId, 20, 'a');
+ opts.fileId = opts.fileId && this.sanitize(opts.fileId, 20, 'a');
const fileId = opts.fileId || Random.id();
const fsName = this.namingFunction ? this.namingFunction(opts) : fileId;
const fileName = (opts.name || opts.fileName) ? (opts.name || opts.fileName) : fsName;
@@ -1340,7 +1346,7 @@ class FilesCollection extends FilesCollectionCore {
opts.timeout = 360000;
}
- const fileId = (opts.fileId && helpers.sanitize(opts.fileId, 20, 'a')) || Random.id();
+ const fileId = (opts.fileId && this.sanitize(opts.fileId, 20, 'a')) || Random.id();
const fsName = this.namingFunction ? this.namingFunction(opts) : fileId;
const pathParts = url.split('/');
const fileName = (opts.name || opts.fileName) ? (opts.name || opts.fileName) : pathParts[pathParts.length - 1].split('?')[0] || fsName;
@@ -1556,7 +1562,7 @@ class FilesCollection extends FilesCollectionCore {
userId: opts.userId,
extension,
_storagePath: path.replace(`${nodePath.sep}${opts.fileName}`, ''),
- fileId: (opts.fileId && helpers.sanitize(opts.fileId, 20, 'a')) || null
+ fileId: (opts.fileId && this.sanitize(opts.fileId, 20, 'a')) || null
});