Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions app/file-upload/server/config/Storj.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import http from 'http';
import https from 'https';

import { Meteor } from 'meteor/meteor';
import _ from 'underscore';

import { settings } from '../../../settings';
import { FileUploadClass, FileUpload } from '../lib/FileUpload';
import '../../ufs/Storj/server.js';

const get = function(file, req, res) {
const forceDownload = typeof req.query.download !== 'undefined';

this.store.getRedirectURL(file, forceDownload, (err, fileUrl) => {
if (err) {
return console.error(err);
}

if (!fileUrl) {
return res.end();
}

return FileUpload.redirectToFile(fileUrl, req, res);
});
};

const copy = function(file, out) {
const fileUrl = this.store.getRedirectURL(file);

if (fileUrl) {
const request = /^https:/.test(fileUrl) ? https : http;
request.get(fileUrl, (fileRes) => fileRes.pipe(out));
} else {
out.end();
}
};

// This is the class that is retrieved when using FileUpload.getStoreByName / FileUpload.getStore
const StorjUploads = new FileUploadClass({
name: 'Storj:Uploads',
get,
copy,
// store setted bellow
});

const StorjAvatars = new FileUploadClass({
name: 'Storj:Avatars',
get,
copy,
// store setted bellow
});

const StorjUserDataFiles = new FileUploadClass({
name: 'Storj:UserDataFiles',
get,
copy,
// store setted bellow
});

const configure = Meteor.bindEnvironment(_.debounce(function() {
const bucketName = settings.get('FileUpload_Storj_Bucket');
const accessKey = settings.get('FileUpload_Storj_AccessKey');

if (!bucketName || !accessKey) {
return;
}

const config = {
accessKey,
bucketName,
};

StorjUploads.store = FileUpload.configureUploadsStore('Storj', StorjUploads.name, config);
StorjAvatars.store = FileUpload.configureUploadsStore('Storj', StorjAvatars.name, config);
StorjUserDataFiles.store = FileUpload.configureUploadsStore('Storj', StorjUserDataFiles.name, config);
}, 500));

settings.get(/^FileUpload_Storj_/, configure);
1 change: 1 addition & 0 deletions app/file-upload/server/config/_configUploadStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import './FileSystem.js';
import './GoogleStorage.js';
import './GridFS.js';
import './Webdav.js';
import './Storj.js';

const configStore = _.debounce(() => {
const store = settings.get('FileUpload_Storage_Type');
Expand Down
1 change: 1 addition & 0 deletions app/file-upload/server/lib/FileUpload.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const FileUpload = {
const stores = UploadFS.getStores();
delete stores[name];

// the class that is instantiated here is the one from ../../ufs/*/server
return new UploadFS.store[store](Object.assign({
name,
}, options, FileUpload[`default${ type }`]()));
Expand Down
38 changes: 38 additions & 0 deletions app/file-upload/server/startup/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ settings.addGroup('FileUpload', function() {
}, {
key: 'FileSystem',
i18nLabel: 'FileSystem',
}, {
key: 'Storj',
i18nLabel: 'Storj',
}],
public: true,
});
Expand Down Expand Up @@ -212,6 +215,41 @@ settings.addGroup('FileUpload', function() {
});
});

this.section('Storj Storage', function() {
this.add('FileUpload_Storj_Bucket', '', {
type: 'string',
private: true,
enableQuery: {
_id: 'FileUpload_Storage_Type',
value: 'Storj',
},
secret: true,
});
this.add('FileUpload_Storj_AccessKey', '', {
type: 'string',
private: true,
enableQuery: {
_id: 'FileUpload_Storage_Type',
value: 'Storj',
},
secret: true,
});
// this.add('FileUpload_Storj_Proxy_Avatars', false, {
// type: 'boolean',
// enableQuery: {
// _id: 'FileUpload_Storage_Type',
// value: 'Storj',
// },
// });
// this.add('FileUpload_Storj_Proxy_Uploads', false, {
// type: 'boolean',
// enableQuery: {
// _id: 'FileUpload_Storage_Type',
// value: 'Storj',
// },
// });
});

this.section('File System', function() {
this.add('FileUpload_FileSystemPath', '', {
type: 'string',
Expand Down
90 changes: 90 additions & 0 deletions app/file-upload/ufs/Storj/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { check } from 'meteor/check';
import { UploadFS } from 'meteor/jalik:ufs';
import { Random } from 'meteor/random';
// import uplink from 'uplink-js';

/**
* Storj store
* @param options
* @constructor
*/

export class StorjStore extends UploadFS.Store {
constructor(options) {
// Default options
// options.accessKey,
// options.bucketName,
super(options);

options.getPath = options.getPath || function(file) {
return file._id;
};

this.bucketName = options.bucketName;

this.getPath = function(file) {
if (file.Storj) {
return file.Storj.path;
}
};

/**
* Creates the file in the collection
* @param file
* @param callback
* @return {string}
*/
this.create = function(file, callback) {
check(file, Object);

if (file._id == null) {
file._id = Random.id();
}

file.Storj = {
path: this.options.getPath(file),
};

file.store = this.options.name; // assign store to file
return this.getCollection().insert(file, callback);
};

/**
* Removes the file
* @param fileId
* @param callback
*/
this.delete = function(fileId, callback) {
this.project.deleteObject(this.bucketName, fileId).then(() => {
callback && callback();
});
};

/**
* Returns the file read stream
* @param fileId
* @param file
* @param options
* @return {*}
*/
this.getReadStream = function(fileId/* , file, options = {}*/) {
const download = Promise.await(this.project.downloadObject(this.bucketName, fileId));
return download.stream();
};

/**
* Returns the file write stream
* @param fileId
* @param file
* @param options
* @return {*}
*/
this.getWriteStream = function(fileId/* , file, options*/) {
const upload = Promise.await(this.project.uploadObject(this.bucketName, fileId));
return upload.stream();
};
}
}

// Add store to UFS namespace
UploadFS.store.Storj = StorjStore;
3 changes: 3 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1726,6 +1726,8 @@
"FileUpload_S3_URLExpiryTimeSpan": "URLs Expiration Timespan",
"FileUpload_S3_URLExpiryTimeSpan_Description": "Time after which Amazon S3 generated URLs will no longer be valid (in seconds). If set to less than 5 seconds, this field will be ignored.",
"FileUpload_Storage_Type": "Storage Type",
"FileUpload_Storj_AccessKey": "Access Key",
"FileUpload_Storj_Bucket": "Bucket Name",
"FileUpload_Webdav_Password": "WebDAV Password",
"FileUpload_Webdav_Proxy_Avatars": "Proxy Avatars",
"FileUpload_Webdav_Proxy_Avatars_Description": "Proxy avatar file transmissions through your server instead of direct access to the asset's URL",
Expand Down Expand Up @@ -3529,6 +3531,7 @@
"Stop_Recording": "Stop Recording",
"Store_Last_Message": "Store Last Message",
"Store_Last_Message_Sent_per_Room": "Store last message sent on each room.",
"Storj": "Storj Storage",
"Stream_Cast": "Stream Cast",
"Stream_Cast_Address": "Stream Cast Address",
"Stream_Cast_Address_Description": "IP or Host of your Rocket.Chat central Stream Cast. E.g. `192.168.1.1:3000` or `localhost:4000`",
Expand Down