Skip to content

Commit

Permalink
Moved file upload from the controller to the middleware.
Browse files Browse the repository at this point in the history
  • Loading branch information
jtpox committed Apr 12, 2018
1 parent 699cff7 commit 9445d97
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 133 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
"extends": "airbnb-base",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
"jsx": false
},
"sourceType": "module"
},
Expand Down
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "airbnb-base"
}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ config/database.json
config/server.json
config/analytics.js
themes/
admin/
admin/
package-lock.json
83 changes: 22 additions & 61 deletions app/controller/authenticate.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,72 +150,33 @@ class Index {

/*
* Updating user display image.
* Image upload has been done via middleware.
* File name is sent to req.upload.
*/
update_avatar(req, res) {
if (req.files) {
// console.log(req.files);
const extension_extract = /(?:\.([^.]+))?$/;
const extension = extension_extract.exec(req.files.file.name);
// console.log(extension[1]);

const allowed_extensions = [
'png',
'gif',
'jpg',
'jpeg',
'bmp',
];

if (allowed_extensions.indexOf(extension[1]) === -1) {
res.json({
error: 1,
});
} else {
// Get current user to check if the avatar is default.
const fields = ['username', 'email', 'about', 'avatar', 'created_at', 'last_updated'];
const user = User.find({ _id: req.currentUser }).select(fields.join(' '));

user.exec((err, results) => {
const current_avatar = Path.join(__dirname, '..', '..', 'public', 'uploads', 'profile', results[0].avatar);
Crypto.randomBytes(12, (crypto_err, buffer) => {
// Generate directory to move the image to.
const directory = Path.join(__dirname, '..', '..', 'public', 'uploads', 'profile', `${buffer.toString('hex')}.${extension[1]}`);
// console.log(directory);

req.files.file.mv(directory, (mv_err) => {
// console.log(mv_err);
if (mv_err) {
res.json({
error: 1,
});
} else {
User.update({ _id: req.currentUser }, { avatar: `${buffer.toString('hex')}.${extension[1]}` }, (update_err) => {
if (update_err) {
res.json({
error: 1,
});
} else {
if (results[0].avatar !== 'default.png') {
// Delete the image if it's not default.png.
Fs.unlink(current_avatar, () => { });
}
// Get current user to check if the avatar is default.
const fields = ['username', 'email', 'about', 'avatar', 'created_at', 'last_updated'];
const user = User.find({ _id: req.currentUser }).select(fields.join(' '));
user.exec((err, results) => {
User.update({ _id: req.currentUser }, { avatar: req.upload }, (update_err) => {
if (update_err) {
res.json({
error: 1,
});
} else {
if (results[0].avatar !== 'default.png') {
// Delete the image if it's not default.png.
const current_avatar = Path.join(__dirname, '..', '..', 'public', 'uploads', 'profile', results[0].avatar);
Fs.unlink(current_avatar, () => { });
}

res.json({
error: 0,
image: `${buffer.toString('hex')}.${extension[1]}`,
});
}
});
}
});
res.json({
error: 0,
image: req.upload,
});
});
}
} else {
res.json({
error: 1,
}
});
}
});
}
}

Expand Down
62 changes: 11 additions & 51 deletions app/controller/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,64 +25,24 @@ class ImageC {

insert(req, res) {
// Add an image.
if (req.files) {
// console.log(req.files);
const extension_extract = /(?:\.([^.]+))?$/;
const extension = extension_extract.exec(req.files.file.name);
// console.log(extension[1]);

const allowed_extensions = [
'png',
'gif',
'jpg',
'jpeg',
'bmp',
];
const image = new Image({
title: req.files.file.name,
file_name: req.upload,
created_by: Db.Types.ObjectId(req.currentUser),
});

if (allowed_extensions.indexOf(extension[1]) === -1) {
image.save((save_err, new_image) => {
if (save_err) {
res.json({
error: 1,
});
} else {
Crypto.randomBytes(12, (err, buffer) => {
// Generate directory to move the image to.
const directory = Path.join(__dirname, '..', '..', 'public', 'uploads', 'images', `${buffer.toString('hex')}.${extension[1]}`);
// console.log(directory);

req.files.file.mv(directory, (mv_err) => {
// console.log(mv_err);
if (mv_err) {
res.json({
error: 1,
});
} else {
const image = new Image({
title: req.files.file.name,
file_name: `${buffer.toString('hex')}.${extension[1]}`,
created_by: Db.Types.ObjectId(req.currentUser),
});

image.save((save_err, new_image) => {
if (save_err) {
res.json({
error: 1,
});
} else {
res.json({
error: 0,
image: new_image,
});
}
});
}
});
res.json({
error: 0,
image: new_image,
});
}
} else {
res.json({
error: 1,
});
}
});
}

delete(req, res) {
Expand Down
90 changes: 90 additions & 0 deletions app/middleware/image_upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Image upload middleware for avatar and image management.
*/
const Crypto = require('crypto');
const Path = require('path');

function filterExtension(file) {
const extension_extract = /(?:\.([^.]+))?$/;
const extension = extension_extract.exec(file.name);
// console.log(extension[1]);

const allowed_extensions = [
'png',
'gif',
'jpg',
'jpeg',
'bmp',
];

if (allowed_extensions.indexOf(extension[1]) === -1) {
return {
extension: extension[1],
output: false,
};
}

return {
extension: extension[1],
output: true,
};
}

function avatar(req, res, next) {
if (req.files) {
const filter = filterExtension(req.files.file); // Check the file extension.
if (filter.output) {
// Generate a random string to be used as a file name.
const file_name = Crypto.randomBytes(12).toString('hex');
const directory = Path.join(__dirname, '..', '..', 'public', 'uploads', 'profile', `${file_name}.${filter.extension}`);
req.files.file.mv(directory, (mv_err) => {
if (mv_err) {
res.json({
error: 1,
});
} else {
req.upload = `${file_name}.${filter.extension}`;
next();
}
});
} else {
res.json({
error: 1,
});
}
} else {
res.json({
error: 1,
});
}
}

function library(req, res, next) {
if (req.files) {
const filter = filterExtension(req.files.file); // Check the file extension.
if (filter.output) {
const file_name = Crypto.randomBytes(12).toString('hex');
const directory = Path.join(__dirname, '..', '..', 'public', 'uploads', 'images', `${file_name}.${filter.extension}`);
req.files.file.mv(directory, (mv_err) => {
if (mv_err) {
res.json({
error: 1,
});
} else {
req.upload = `${file_name}.${filter.extension}`;
next();
}
});
} else {
res.json({
error: 1,
});
}
} else {
res.json({
error: 1,
});
}
}

module.exports = { avatar, library };
6 changes: 4 additions & 2 deletions app/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*/
const AuthMid = require('./middleware/auth');

const ImageMid = require('./middleware/image_upload');

/*
* Instantiating all controller classes.
*/
Expand Down Expand Up @@ -44,7 +46,7 @@ function routes(app) {
app.post('/api/auth/logout', AuthMid.isLogged, auth.logout);

app.post('/api/auth/update/about', AuthMid.isLogged, auth.update_about);
app.post('/api/auth/update/avatar', AuthMid.isLogged, auth.update_avatar);
app.post('/api/auth/update/avatar', [AuthMid.isLogged, ImageMid.avatar], auth.update_avatar);
app.post('/api/auth/details', AuthMid.isLogged, auth.details);

app.get('/api', blog.site);
Expand Down Expand Up @@ -93,7 +95,7 @@ function routes(app) {

// app.put('/api/images', AuthMid.isLogged, image.list);// PUT as GET doesn't allow body.
app.get('/api/images', AuthMid.isLogged, image.list);
app.post('/api/images', AuthMid.isLogged, image.insert);
app.post('/api/images', [AuthMid.isLogged, ImageMid.library], image.insert);

app.delete('/api/images/:id', AuthMid.isLogged, image.delete);
app.post('/api/images/delete/:id', AuthMid.isLogged, image.delete);
Expand Down
Loading

0 comments on commit 9445d97

Please sign in to comment.