Double backslash into path - node.js

I have using this the tuttorial of Academind how to load image using multer into node JavaScript rest service.
About path destination folder I use this code:
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './uploads/');
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5
},
fileFilter: fileFilter
});
But the path generated have double backslash that show as one backslash:
uploads\2018-09-16T13-02-45.535Z1536685465dummy4.jpg
How I can replace destination path with slash?

i had the same issue, and since i didn't find anything i did this as a work around
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
cb(null, `${new Date().toISOString().replace(/:/g, '-')}${file.originalname.split(" ").join("_")}`);
}
});
const user= new User({
_id : new mongoose.Types.ObjectId(),
name : req.body.name,
image: req.file.destination + req.file.filename,
});

Related

multer saves image in a weird format

I am trying to serve an image from my Express server to my client but multer is saving the file in a weird format which leads to issues when my react app tries to render the image
multer server side code:
const fileFilter = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png'){
// accept a file
cb(null, true);
} else {
// reject a file
cb(new Error('Incorrect file'), false);
}
}
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname))
}
});
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5 // max 5mb for image size
},
fileFilter: fileFilter
});
router.post('/', upload.single('productImage'), ProductsController.products_create_product);
This code successfully creates the file in the /uploads folder but when I save the path to the database I get this response:
Postman
{
"size": 5,
"quantityInStock": 11,
"productImage": "uploads\\2021-03-11T19-18-05.442Zvans-2.jpg",
}
How can I change it so it saves the image in this format: /uploads/2021-03-11T19-18-05.442Zvans-2.jpg
You just need to fix your destination path like this:
cb(null, path.join(__dirname, './uploads/'));
For me this was the full code-block. Just grab the actual part you want:
const multer = require('multer');
const path = require('path');
const appConfigs = require('./../config/app');
module.exports = function (folderName) {
// TODO: console log here and optimize multiple initialization of multer if need
return multer({
storage: multer.diskStorage({
destination: function (req, file, cb) {
const filePath = path.join(__dirname, './../uploads/' + folderName);
cb(null, filePath);
},
filename: function (req, file, cb) {
const extension = file.mimetype.split('/')[1];
const fileName = (new Date().getTime() / 1000 | 0) + '.' + extension;
cb(null, fileName);
}
}),
limits: {
fileSize: 1024 * 1024 * appConfigs.image_max_size // MB
},
fileFilter: (req, file, cb) => {
let valid = (file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype === 'image/png');
cb(null, valid);
},
});
};

Multer upload an image to node js server (Github as storage)

I deployed a web based application but the multer upload doesn't work. It does work in localhost there is no error but the file/s are not save in my director. Here is my code:
const multer = require("multer");
const imageFilter = (req, file, cb) => {
if (file.mimetype.startsWith("image")) {
cb(null, true);
} else {
cb("Please upload only images.", false);
}
};
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, __basedir + "/resources/static/assets/uploads/");
},
filename: (req, file, cb) => {
cb(null, `${file.originalname}`);
},
});
var uploadFile = multer({ storage: storage, fileFilter: imageFilter });
module.exports = uploadFile;
What happen is the __basedir expression will cause "Uncaught ReferenceError: __basedir is not defined" error, but it's silently eaten in the code. To get the error to properly propagate, try adding try-catch block around the offending line this:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
try {
cb(null, __basedir + "/resources/static/assets/uploads/");
} catch (e) {
cb(e);
}
},
filename: (req, file, cb) => {
cb(null, `${file.originalname}`);
}
});

UPLOAD FILE VULNERABILITY with multer

I am using multer to upload file in my application.
like: https://github.com/expressjs/multer/blob/master/README.md
Can path traversal vulnerability possible ? If yes then tell us how we can stop this?
Currenlty, I am using below code. I just want to confirm, Is there any file vulnerable risk? Please comment.
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'uploads/');
},
filename: function (req, file, cb) {
console.log(file);
var ext = file.originalname.split('.').pop();
cb(null, Date.now() + '_' + file.originalname);
}});
const fileFilter = (req, file, cb) => {
// Accept or reject the file based on if MIME type is found in accepted list
if (acceptedMimeTypes.indexOf(file.mimetype) < 0) {
return cb("エラー:このタイプのファイルはアップロードできません。ZIP形式とLZH形式のファイルのみアップロードしてください。", false) // Error: You can't upload files of this type. Please upload images and zips only.
}
else {
return cb(null, true);
}
}
var upload = multer({ storage: storage, fileFilter: fileFilter, limits: { fileSize: 1024 * 1024 * 1 } }).single('file');
If there is any risk then please suggest me a better approach with expressjs multer.
You can modify the fileName using this code so no one can threaten you :
const storage = multer.diskStorage({
destination: './public',
filename(req, file, cb) {
cb(null, 'Your File Name');
},
});
and also you can make it dynamic using randomatic and time like this :
const storage = multer.diskStorage({
destination: './public',
filename(req, file, cb) {
cb(null, `${new Date().getTime()}`);
},
});

Multer: fileFilter not working

I'm using multer to upload files. everything is goung fine but fileFilter is not working. I've no idea where i'm going wrong.
routes.js
var multer = require('multer');
// Multer diskStorage setting
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads/');
},
filFilter: function (req, file, cb) {
var typeArray = file.mimetype.split('/');
var fileType = typeArray[1];
if (fileType == 'jpg' || fileType == 'png') {
cb(null, true);
} else {
cb(null, false)
}
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '_' + Date.now() + '.jpg');
}
});
var upload = multer({ storage: storage });
router.post('/add', upload.single('photo'), function(req, res){
console.log('uploaded');
}
Multer also uploads files other than allowed. Any idea?
fileFilter must be defined in multer's options object rather than diskStorage
const uploadFilter = function(req, file, cb) {
// filter rules here
}
const upload = multer({
storage: storage,
fileFilter: uploadFilter,
});
const storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads/');
},
fileFilter: function (req, file, cb) {
const extension = path.extname(file.originalname).toLowerCase();
const mimetyp = file.mimetype;
if (
extension !== '.jpg' ||
extension !== '.jpeg' ||
extension !== '.png' ||
mimetyp !== 'image/png' ||
mimetyp !== 'image/jpg' ||
mimetyp !== 'image/jpeg'
) {
cb('error message', true);
}
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '_' + Date.now() + '.jpg');
},
});
const upload = multer({ storage: storage });
router.post('/add', upload.single('photo'), function (req, res) {
console.log('uploaded');
});
i think this will help
You have a typo at your fileFilter; you've named it filFilter.
Could you change your code to the following and tell us if it worked out?
var multer = require('multer');
// Multer diskStorage setting
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads/');
},
fileFilter: function (req, file, cb) {
var typeArray = file.mimetype.split('/');
var fileType = typeArray[1];
if (fileType == 'jpg' || fileType == 'png') {
cb(null, true);
} else {
cb(null, false)
}
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '_' + Date.now() + '.jpg');
}
});
var upload = multer({ storage: storage });
router.post('/add', upload.single('photo'), function(req, res){
console.log('uploaded');
}

Multer is storing in local AppData and not in specified directory

I am using Multer with my MEAN2 stack and I have got file uploading working fine through ng2-uploader.
But I am trying to upload it to the server so i can then parse the csv file to json, but that is not the issue.
The file uploads fine ... but it uploads it to AppData\Local\Temp, here is the file information once uploaded:
[ { fieldname: 'file',
originalname: 'sfgsgsfrfs.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'C:\\Users\\Jezyk\\AppData\\Local\\Temp',
filename: 'z83yrcprp4m8azfflxr.jpg',
path: 'C:\\Users\\Jezyk\\AppData\\Local\\Temp\\z83yrcprp4m8azfflxr.jpg',
size: 120850 } ]
and here is my code that I am using to store the file:
const upload = multer({
dest: './server/uploads/',
storage: multer.diskStorage({
filename: (req, file, cb) => {
let ext = path.extname(file.originalname);
cb(null, `${Math.random().toString(36).substring(7)}${ext}`);
}
})
});
router.route('/upload').post(upload.any(), (req, res) => {
console.log(req.files);
res.json(req.files.map(file => {
let ext = path.extname(file.originalname);
return {
originalName: file.originalname,
filename: file.filename
}
}));
});
Any idea why it is doing so?
You need to add a destination callback if using an explicit, configured storage instance:
const upload = multer({
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, __dirname + '/server/uploads/')
},
filename: (req, file, cb) => {
let ext = path.extname(file.originalname);
cb(null, `${Math.random().toString(36).substring(7)}${ext}`);
}
})
});

Resources