Move GridFS to uploads package and resuse more code

pull/6788/head
Rodrigo Nascimento 9 years ago
parent 2783e70179
commit 75b0a1969f
  1. 136
      lib/fileUpload.js
  2. 5
      packages/rocketchat-file-upload/client/lib/FileUploadGridFS.js
  3. 1
      packages/rocketchat-file-upload/package.js
  4. 85
      packages/rocketchat-file-upload/server/config/configFileUploadAmazonS3.js
  5. 45
      packages/rocketchat-file-upload/server/config/configFileUploadFileSystem.js
  6. 84
      packages/rocketchat-file-upload/server/config/configFileUploadGoogleStorage.js
  7. 61
      packages/rocketchat-file-upload/server/config/configFileUploadGridFS.js
  8. 106
      packages/rocketchat-file-upload/server/lib/FileUpload.js

@ -1,136 +0,0 @@
/* globals UploadFS, FileUpload */
import { Cookies } from 'meteor/ostrio:cookies';
if (UploadFS) {
const initFileStore = function() {
const cookie = new Cookies();
if (Meteor.isClient) {
document.cookie = `rc_uid=${ escape(Meteor.userId()) }; path=/`;
document.cookie = `rc_token=${ escape(Accounts._storedLoginToken()) }; path=/`;
}
Meteor.fileStore = new UploadFS.store.GridFS({
collection: RocketChat.models.Uploads.model,
name: 'GridFS:Uploads',
collectionName: 'rocketchat_uploads',
filter: new UploadFS.Filter({
onCheck: FileUpload.validateFileUpload
}),
transformWrite(readStream, writeStream, fileId, file) {
if (RocketChatFile.enabled === false || !/^image\/.+/.test(file.type)) {
return readStream.pipe(writeStream);
}
let stream = undefined;
const identify = function(err, data) {
if (err) {
return stream.pipe(writeStream);
}
file.identify = {
format: data.format,
size: data.size
};
if (data.Orientation && !['', 'Unknown', 'Undefined'].includes(data.Orientation)) {
RocketChatFile.gm(stream).autoOrient().stream().pipe(writeStream);
} else {
stream.pipe(writeStream);
}
};
stream = RocketChatFile.gm(readStream).identify(identify).stream();
},
onRead(fileId, file, req, res) {
if (RocketChat.settings.get('FileUpload_ProtectFiles')) {
let uid;
let token;
if (req && req.headers && req.headers.cookie) {
const rawCookies = req.headers.cookie;
if (rawCookies) {
uid = cookie.get('rc_uid', rawCookies) ;
token = cookie.get('rc_token', rawCookies);
}
}
if (!uid) {
uid = req.query.rc_uid;
token = req.query.rc_token;
}
if (!uid || !token || !RocketChat.models.Users.findOneByIdAndLoginToken(uid, token)) {
res.writeHead(403);
return false;
}
}
res.setHeader('content-disposition', `attachment; filename="${ encodeURIComponent(file.name) }"`);
return true;
}
});
// DEPRECATED: backwards compatibility (remove)
UploadFS.getStores()['rocketchat_uploads'] = UploadFS.getStores()['GridFS:Uploads'];
Meteor.fileStoreAvatar = new UploadFS.store.GridFS({
collection: RocketChat.models.Avatars.model,
name: 'GridFS:Avatars',
collectionName: 'rocketchat_avatars',
// filter: new UploadFS.Filter({
// onCheck: FileUpload.validateFileUpload
// }),
transformWrite: FileUpload.avatarTransformWrite,
onFinishUpload(file) {
// update file record to match user's username
const user = RocketChat.models.Users.findOneById(file.userId);
const oldAvatar = RocketChat.models.Avatars.findOneByName(user.username);
if (oldAvatar) {
Meteor.fileStoreAvatar.delete(oldAvatar._id);
RocketChat.models.Avatars.deleteFile(oldAvatar._id);
}
RocketChat.models.Avatars.updateFileNameById(file._id, user.username);
// console.log('upload finished ->', file);
},
onRead(fileId, file, req, res) {
if (RocketChat.settings.get('FileUpload_ProtectFiles')) {
let uid;
let token;
if (req && req.headers && req.headers.cookie) {
const rawCookies = req.headers.cookie;
if (rawCookies) {
uid = cookie.get('rc_uid', rawCookies) ;
token = cookie.get('rc_token', rawCookies);
}
}
if (!uid) {
uid = req.query.rc_uid;
token = req.query.rc_token;
}
if (!uid || !token || !RocketChat.models.Users.findOneByIdAndLoginToken(uid, token)) {
res.writeHead(403);
return false;
}
}
res.setHeader('content-disposition', `attachment; filename="${ encodeURIComponent(file.name) }"`);
return true;
}
});
};
Meteor.startup(function() {
if (Meteor.isServer) {
initFileStore();
}
});
}

@ -16,3 +16,8 @@ new UploadFS.store.GridFS({
onCheck: FileUpload.validateFileUpload
})
});
Tracker.autorun(function() {
document.cookie = `rc_uid=${ escape(Meteor.userId()) }; path=/`;
document.cookie = `rc_token=${ escape(Accounts._storedLoginToken()) }; path=/`;
});

@ -18,6 +18,7 @@ Package.onUse(function(api) {
api.use('peerlibrary:aws-sdk');
api.use('rocketchat:lib');
api.use('random');
api.use('accounts-base');
api.use('underscore');
api.use('tracker');
api.use('webapp');

@ -1,11 +1,8 @@
/* globals FileUpload, UploadFS, RocketChatFile */
import fs from 'fs';
import { FileUploadClass } from '../lib/FileUpload';
import '../../ufs/AmazonS3/server.js';
const Future = Npm.require('fibers/future');
const insert = function(file, stream, cb) {
const fileId = this.store.create(file);
@ -38,46 +35,6 @@ const AmazonS3Avatars = new FileUploadClass({
insert
});
const onValidate = function(file) {
if (RocketChatFile.enabled === false || !/^image\/((x-windows-)?bmp|p?jpeg|png)$/.test(file.type)) {
return;
}
const tmpFile = UploadFS.getTempFilePath(file._id);
const fut = new Future();
const identify = Meteor.bindEnvironment((err, data) => {
if (err != null) {
console.error(err);
return fut.return();
}
file.identify = {
format: data.format,
size: data.size
};
if ([null, undefined, '', 'Unknown', 'Undefined'].includes(data.Orientation)) {
return fut.return();
}
RocketChatFile.gm(tmpFile).autoOrient().write(tmpFile, Meteor.bindEnvironment((err) => {
if (err != null) {
console.error(err);
}
const size = fs.lstatSync(tmpFile).size;
this.getCollection().direct.update({_id: file._id}, {$set: {size}});
fut.return();
}));
});
RocketChatFile.gm(tmpFile).identify(identify);
return fut.wait();
};
const configure = _.debounce(function() {
const stores = UploadFS.getStores();
delete stores[AmazonS3Uploads.name];
@ -112,50 +69,14 @@ const configure = _.debounce(function() {
onCheck: FileUpload.validateFileUpload
}),
name: AmazonS3Uploads.name,
onValidate
onValidate: FileUpload.uploadsOnValidate
}, config));
AmazonS3Avatars.store = new UploadFS.store.AmazonS3(Object.assign({
collection: AmazonS3Avatars.model.model,
name: AmazonS3Avatars.name,
onFinishUpload(file) {
// update file record to match user's username
const user = RocketChat.models.Users.findOneById(file.userId);
const oldAvatar = AmazonS3Avatars.model.findOneByName(user.username);
if (oldAvatar) {
try {
AmazonS3Avatars.deleteById(oldAvatar._id);
} catch (e) {
console.error(e);
}
}
AmazonS3Avatars.model.updateFileNameById(file._id, user.username);
// console.log('upload finished ->', file);
},
onValidate(file) {
if (RocketChatFile.enabled === false || RocketChat.settings.get('Accounts_AvatarResize') !== true) {
return;
}
const tmpFile = UploadFS.getTempFilePath(file._id);
const fut = new Future();
const height = RocketChat.settings.get('Accounts_AvatarSize');
const width = height;
RocketChatFile.gm(tmpFile).background('#ffffff').resize(width, `${ height }^`).gravity('Center').crop(width, height).extent(width, height).setFormat('jpeg').write(tmpFile, Meteor.bindEnvironment((err) => {
if (err != null) {
console.error(err);
}
const size = fs.lstatSync(tmpFile).size;
this.getCollection().direct.update({_id: file._id}, {$set: {size}});
fut.return();
}));
return fut.wait();
}
onFinishUpload: FileUpload.avatarsOnFinishUpload,
onValidate: FileUpload.avatarsOnValidate
}, config));
}, 500);

@ -78,34 +78,6 @@ const FileSystemAvatars = new FileUploadClass({
});
const transformWrite = function(readStream, writeStream, fileId, file) {
if (RocketChatFile.enabled === false || !/^image\/((x-windows-)?bmp|p?jpeg|png)$/.test(file.type)) {
return readStream.pipe(writeStream);
}
let stream = undefined;
const identify = function(err, data) {
if (err != null) {
return stream.pipe(writeStream);
}
file.identify = {
format: data.format,
size: data.size
};
if ([null, undefined, '', 'Unknown', 'Undefined'].indexOf(data.Orientation) === -1) {
return RocketChatFile.gm(stream).autoOrient().stream().pipe(writeStream);
} else {
return stream.pipe(writeStream);
}
};
stream = RocketChatFile.gm(readStream).identify(identify).stream();
return;
};
const createFileSystemStore = _.debounce(function() {
const stores = UploadFS.getStores();
delete stores['FileSystem:Uploads'];
@ -118,7 +90,7 @@ const createFileSystemStore = _.debounce(function() {
onCheck: FileUpload.validateFileUpload
}),
name: FileSystemUploads.name,
transformWrite
transformWrite: FileUpload.uploadsTransformWrite
});
UploadFS.getStores()['fileSystem'] = UploadFS.getStores()[FileSystemUploads.name];
@ -128,20 +100,7 @@ const createFileSystemStore = _.debounce(function() {
collection: FileSystemAvatars.model.model,
name: FileSystemAvatars.name,
transformWrite: FileUpload.avatarTransformWrite,
onFinishUpload(file) {
// update file record to match user's username
const user = RocketChat.models.Users.findOneById(file.userId);
const oldAvatar = FileSystemAvatars.model.findOneByName(user.username);
if (oldAvatar) {
try {
FileSystemAvatars.deleteById(oldAvatar._id);
} catch (e) {
console.error(e);
}
}
FileSystemAvatars.model.updateFileNameById(file._id, user.username);
// console.log('upload finished ->', file);
}
onFinishUpload: FileUpload.avatarsOnFinishUpload
});
}, 500);

@ -1,10 +1,8 @@
/* globals FileUpload, UploadFS, RocketChatFile */
import fs from 'fs';
import { FileUploadClass } from '../lib/FileUpload';
import '../../ufs/GoogleStorage/server.js';
const Future = Npm.require('fibers/future');
const insert = function(file, stream, cb) {
const fileId = this.store.create(file);
@ -42,46 +40,6 @@ const GoogleCloudStorageAvatars = new FileUploadClass({
insert
});
const onValidate = function(file) {
if (RocketChatFile.enabled === false || !/^image\/((x-windows-)?bmp|p?jpeg|png)$/.test(file.type)) {
return;
}
const tmpFile = UploadFS.getTempFilePath(file._id);
const fut = new Future();
const identify = Meteor.bindEnvironment((err, data) => {
if (err != null) {
console.error(err);
return fut.return();
}
file.identify = {
format: data.format,
size: data.size
};
if ([null, undefined, '', 'Unknown', 'Undefined'].includes(data.Orientation)) {
return fut.return();
}
RocketChatFile.gm(tmpFile).autoOrient().write(tmpFile, Meteor.bindEnvironment((err) => {
if (err != null) {
console.error(err);
}
const size = fs.lstatSync(tmpFile).size;
this.getCollection().direct.update({_id: file._id}, {$set: {size}});
fut.return();
}));
});
RocketChatFile.gm(tmpFile).identify(identify);
return fut.wait();
};
const configure = _.debounce(function() {
const stores = UploadFS.getStores();
delete stores[GoogleCloudStorageUploads.name];
@ -110,50 +68,14 @@ const configure = _.debounce(function() {
onCheck: FileUpload.validateFileUpload
}),
name: GoogleCloudStorageUploads.name,
onValidate
onValidate: FileUpload.uploadsOnValidate
}, config));
GoogleCloudStorageAvatars.store = new UploadFS.store.GoogleStorage(Object.assign({
collection: GoogleCloudStorageAvatars.model.model,
name: GoogleCloudStorageAvatars.name,
onFinishUpload(file) {
// update file record to match user's username
const user = RocketChat.models.Users.findOneById(file.userId);
const oldAvatar = GoogleCloudStorageAvatars.model.findOneByName(user.username);
if (oldAvatar) {
try {
GoogleCloudStorageAvatars.deleteById(oldAvatar._id);
} catch (e) {
console.error(e);
}
}
GoogleCloudStorageAvatars.model.updateFileNameById(file._id, user.username);
// console.log('upload finished ->', file);
},
onValidate(file) {
if (RocketChatFile.enabled === false || RocketChat.settings.get('Accounts_AvatarResize') !== true) {
return;
}
const tmpFile = UploadFS.getTempFilePath(file._id);
const fut = new Future();
const height = RocketChat.settings.get('Accounts_AvatarSize');
const width = height;
RocketChatFile.gm(tmpFile).background('#ffffff').resize(width, `${ height }^`).gravity('Center').crop(width, height).extent(width, height).setFormat('jpeg').write(tmpFile, Meteor.bindEnvironment((err) => {
if (err != null) {
console.error(err);
}
const size = fs.lstatSync(tmpFile).size;
this.getCollection().direct.update({_id: file._id}, {$set: {size}});
fut.return();
}));
return fut.wait();
}
onFinishUpload: FileUpload.avatarsOnFinishUpload,
onValidate: FileUpload.avatarsOnValidate
}, config));
}, 500);

@ -4,6 +4,9 @@ import zlib from 'zlib';
import util from 'util';
import { FileUploadClass } from '../lib/FileUpload';
import { Cookies } from 'meteor/ostrio:cookies';
const cookie = new Cookies();
const logger = new Logger('FileUpload');
@ -127,6 +130,64 @@ const readFromGridFS = function(storeName, fileId, file, headers, req, res) {
}
};
const onRead = function(fileId, file, req, res) {
if (RocketChat.settings.get('FileUpload_ProtectFiles')) {
let uid;
let token;
if (req && req.headers && req.headers.cookie) {
const rawCookies = req.headers.cookie;
if (rawCookies) {
uid = cookie.get('rc_uid', rawCookies) ;
token = cookie.get('rc_token', rawCookies);
}
}
if (!uid) {
uid = req.query.rc_uid;
token = req.query.rc_token;
}
if (!uid || !token || !RocketChat.models.Users.findOneByIdAndLoginToken(uid, token)) {
res.writeHead(403);
return false;
}
}
res.setHeader('content-disposition', `attachment; filename="${ encodeURIComponent(file.name) }"`);
return true;
};
Meteor.fileStore = new UploadFS.store.GridFS({
collection: RocketChat.models.Uploads.model,
name: 'GridFS:Uploads',
collectionName: 'rocketchat_uploads',
filter: new UploadFS.Filter({
onCheck: FileUpload.validateFileUpload
}),
transformWrite: FileUpload.uploadsTransformWrite,
onRead
});
// DEPRECATED: backwards compatibility (remove)
UploadFS.getStores()['rocketchat_uploads'] = UploadFS.getStores()['GridFS:Uploads'];
Meteor.fileStoreAvatar = new UploadFS.store.GridFS({
collection: RocketChat.models.Avatars.model,
name: 'GridFS:Avatars',
collectionName: 'rocketchat_avatars',
// filter: new UploadFS.Filter({
// onCheck: FileUpload.validateFileUpload
// }),
transformWrite: FileUpload.avatarTransformWrite,
onFinishUpload: FileUpload.avatarsOnFinishUpload,
onRead
});
const insert = function(file, stream, cb) {
const fileId = this.store.create(file);

@ -1,6 +1,8 @@
/* globals UploadFS */
import fs from 'fs';
import mime from 'mime-type/with-db';
import Future from 'fibers/future';
Object.assign(FileUpload, {
handlers: {},
@ -14,6 +16,110 @@ Object.assign(FileUpload, {
return RocketChatFile.gm(readStream).background('#ffffff').resize(width, `${ height }^`).gravity('Center').crop(width, height).extent(width, height).stream('jpeg').pipe(writeStream);
},
avatarsOnValidate(file) {
if (RocketChatFile.enabled === false || RocketChat.settings.get('Accounts_AvatarResize') !== true) {
return;
}
const tmpFile = UploadFS.getTempFilePath(file._id);
const fut = new Future();
const height = RocketChat.settings.get('Accounts_AvatarSize');
const width = height;
RocketChatFile.gm(tmpFile).background('#ffffff').resize(width, `${ height }^`).gravity('Center').crop(width, height).extent(width, height).setFormat('jpeg').write(tmpFile, Meteor.bindEnvironment((err) => {
if (err != null) {
console.error(err);
}
const size = fs.lstatSync(tmpFile).size;
this.getCollection().direct.update({_id: file._id}, {$set: {size}});
fut.return();
}));
return fut.wait();
},
uploadsTransformWrite(readStream, writeStream, fileId, file) {
if (RocketChatFile.enabled === false || !/^image\/.+/.test(file.type)) {
return readStream.pipe(writeStream);
}
let stream = undefined;
const identify = function(err, data) {
if (err) {
return stream.pipe(writeStream);
}
file.identify = {
format: data.format,
size: data.size
};
if (data.Orientation && !['', 'Unknown', 'Undefined'].includes(data.Orientation)) {
RocketChatFile.gm(stream).autoOrient().stream().pipe(writeStream);
} else {
stream.pipe(writeStream);
}
};
stream = RocketChatFile.gm(readStream).identify(identify).stream();
},
uploadsOnValidate(file) {
if (RocketChatFile.enabled === false || !/^image\/((x-windows-)?bmp|p?jpeg|png)$/.test(file.type)) {
return;
}
const tmpFile = UploadFS.getTempFilePath(file._id);
const fut = new Future();
const identify = Meteor.bindEnvironment((err, data) => {
if (err != null) {
console.error(err);
return fut.return();
}
file.identify = {
format: data.format,
size: data.size
};
if ([null, undefined, '', 'Unknown', 'Undefined'].includes(data.Orientation)) {
return fut.return();
}
RocketChatFile.gm(tmpFile).autoOrient().write(tmpFile, Meteor.bindEnvironment((err) => {
if (err != null) {
console.error(err);
}
const size = fs.lstatSync(tmpFile).size;
this.getCollection().direct.update({_id: file._id}, {$set: {size}});
fut.return();
}));
});
RocketChatFile.gm(tmpFile).identify(identify);
return fut.wait();
},
avatarsOnFinishUpload(file) {
// update file record to match user's username
const user = RocketChat.models.Users.findOneById(file.userId);
const oldAvatar = RocketChat.models.Avatars.findOneByName(user.username);
if (oldAvatar) {
this.delete(oldAvatar._id);
RocketChat.models.Avatars.deleteFile(oldAvatar._id);
}
RocketChat.models.Avatars.updateFileNameById(file._id, user.username);
// console.log('upload finished ->', file);
},
addExtensionTo(file) {
if (mime.lookup(file.name) === file.type) {
return file;

Loading…
Cancel
Save