Save profile images to Amazon S3 (#1857)

* Profile Image to S3

* Delete image from S3
Fix file deletion

* S3 refactoring
This commit is contained in:
Ghalleb
2017-09-20 04:47:41 +08:00
committed by Michael Leanos
parent 36887dc3a8
commit f146cbc4b2
6 changed files with 93 additions and 18 deletions

View File

@@ -9,12 +9,27 @@ var _ = require('lodash'),
errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
mongoose = require('mongoose'),
multer = require('multer'),
multerS3 = require('multer-s3'),
aws = require('aws-sdk'),
amazonS3URI = require('amazon-s3-uri'),
config = require(path.resolve('./config/config')),
User = mongoose.model('User'),
validator = require('validator');
var whitelistedFields = ['firstName', 'lastName', 'email', 'username'];
var useS3Storage = config.uploads.storage === 's3' && config.aws.s3;
var s3;
if (useS3Storage) {
aws.config.update({
accessKeyId: config.aws.s3.accessKeyId,
secretAccessKey: config.aws.s3.secretAccessKey
});
s3 = new aws.S3();
}
/**
* Update user details
*/
@@ -57,10 +72,24 @@ exports.update = function (req, res) {
exports.changeProfilePicture = function (req, res) {
var user = req.user;
var existingImageUrl;
var multerConfig;
if (useS3Storage) {
multerConfig = {
storage: multerS3({
s3: s3,
bucket: config.aws.s3.bucket,
acl: 'public-read'
})
};
} else {
multerConfig = config.uploads.profile.image;
}
// Filtering to upload only images
var multerConfig = config.uploads.profile.image;
multerConfig.fileFilter = require(path.resolve('./config/lib/multer')).imageFileFilter;
var upload = multer(multerConfig).single('newProfilePicture');
if (user) {
@@ -95,7 +124,9 @@ exports.changeProfilePicture = function (req, res) {
function updateUser() {
return new Promise(function (resolve, reject) {
user.profileImageURL = config.uploads.profile.image.dest + req.file.filename;
user.profileImageURL = config.uploads.storage === 's3' && config.aws.s3 ?
req.file.location :
'/' + req.file.path;
user.save(function (err, theuser) {
if (err) {
reject(err);
@@ -109,24 +140,47 @@ exports.changeProfilePicture = function (req, res) {
function deleteOldImage() {
return new Promise(function (resolve, reject) {
if (existingImageUrl !== User.schema.path('profileImageURL').defaultValue) {
fs.unlink(existingImageUrl, function (unlinkError) {
if (unlinkError) {
if (useS3Storage) {
try {
var { region, bucket, key } = amazonS3URI(existingImageUrl);
var params = {
Bucket: config.aws.s3.bucket,
Key: key
};
// If file didn't exist, no need to reject promise
if (unlinkError.code === 'ENOENT') {
console.log('Removing profile image failed because file did not exist.');
return resolve();
}
s3.deleteObject(params, function (err) {
if (err) {
console.log('Error occurred while deleting old profile picture.');
console.log('Check if you have sufficient permissions : ' + err);
}
console.error(unlinkError);
reject({
message: 'Error occurred while deleting old profile picture'
resolve();
});
} else {
resolve();
} catch (err) {
console.warn(`${existingImageUrl} is not a valid S3 uri`);
return resolve();
}
});
} else {
fs.unlink(path.resolve('.' + existingImageUrl), function (unlinkError) {
if (unlinkError) {
// If file didn't exist, no need to reject promise
if (unlinkError.code === 'ENOENT') {
console.log('Removing profile image failed because file did not exist.');
return resolve();
}
console.error(unlinkError);
reject({
message: 'Error occurred while deleting old profile picture'
});
} else {
resolve();
}
});
}
} else {
resolve();
}