Req.body is Empty inside express router - node.js

I have this router and I'm using multer to store files. I need to varify is 'Key' Exists in the server. Only after that server will store the file.
router.post('/', (req, res) => {
console.log(req.body.key); // empty here
upload(req, res, async (err) => {
if (err) {
console.log(err);
res.send({ error: err.message });
} else {
console.log(req.body.key); //shows the key
store(req.file.filename, {filename: req.file.filename, downloaded: 0, key: req.body.key});
res.send({ success: true, downlink: req.file.filename});
}
});
});
let storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, 'uploads/'),
filename: (req, file, cb) => {
const filename = `${uuid()}-${file.originalname}`;
cb(null, filename);
}
});
let upload = multer({
storage: storage,
limits: { fileSize: 15000000 },
}).single('file'); //name field name
How can I add a checkpoint to prevent Unauthorized file upload?
https://i.stack.imgur.com/gZAHE.png

Related

Multer typescript error next(err) is not a function

I am developing a MEAN stack app for photo upload and I'm encountering an issue with the follow error. Currently testing this endpoint with postman, everytime I upload an image to the folder the server will stop running and I recieve this error. Any help would be appreciated
node_modules\multer\lib\make-middleware.js:45make-middleware.js:45
next(err)
^
TypeError: next is not a function
In my post.controller.js
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads');
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now() + '-' + getExtension(file));
},
});
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5,
},
});
const getExtension = (file) => {
// this function gets the filename extension by determining mimetype. To be exanded to support others, for example .jpeg or .tiff
var res = '';
if (file.mimetype === 'image/jpeg') res = '.jpg';
if (file.mimetype === 'image/png') res = '.png';
return res;
};
(exports.create = upload.single('imagePath')),
async (req, res, next) => {
try {
console.log(req.file, req.body);
const { title, date } = req.body;
const imagePath = req.file.path;
const post = new Posts({
title,
date,
imagePath,
});
await post.save();
return res.status(200).json({
success: true,
post,
});
} catch (error) {
return res.status(500).json({
success: false,
message: 'Server Error',
error: error,
});
}
};
And my posts.route.js
const express = require('express');
const PostsController = require('../controllers/posts.controller');
const Auth = require('../auth/auth');
const multer = require('multer');
const route = express.Router();
route.post('/create', Auth.authenticateJWT, (req, res) => {
PostsController.create(req, res);
});
route.get('/', Auth.authenticateJWT, (req, res) => {
PostsController.getAllPosts(req, res);
});
route.get('/:id', Auth.authenticateJWT, (req, res) => {
PostsController.getPost(req, res);
});
module.exports = route;
You should define create as:
exports.create = async (req, res, next) => {
try {
console.log(req.file, req.body);
const { title, date } = req.body;
const imagePath = req.file.path;
const post = new Posts({
title,
date,
imagePath,
});
await post.save();
return res.status(200).json({
success: true,
post,
});
} catch (error) {
return res.status(500).json({
success: false,
message: 'Server Error',
error: error,
});
}
};
Export the upload variable:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads');
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now() + '-' + getExtension(file));
},
});
exports.upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5,
},
});
And use it as a middleware:
route.post('/create', Auth.authenticateJWT, PostsController.upload('imagePath'), PostsController.create);

Image gets saved as a .txt file

I am using multer to save an image from the client to mongoDB, and then rendering that image to the client as per the requirement.
When attempting to save the image from the frontend, it is getting saved as a .txt document.
How do I save it as a .png? (I am using Express on Node)
var multer = require('multer');
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'src/');
},
filename: function(req, file, cb) {
cb(null, new Date().toISOString().replace(/:/g, '-')+ file.originalname);
}
});
var upload = multer({ storage: storage });
app.post('/test', upload.single('image'), (req, res, next) => {
var obj = {
name: req.body.name,
desc: req.body.desc,
img: {
data: fs.readFileSync(path.join(__dirname + '/src/' + req.file.filename)),
contentType: 'image/png'
}
}
Image.create(obj, (err, item) => {
if (err) {
console.log(err);
}
else {
item.save();
res.redirect('/admin');
}
});
});
Frontend
<img src="data:image/<%=image.img.contentType%>;base64,
<%=image.img.data.toString('base64')%>">
Upon clicking "Save as"
download.txt

why image is saving as text file in node js

Here i'm trying to save the image in database using multer but image type is saving as a text format but not in .png , .jpeg, .jpg format,
PLease help me where i'm doing wrong thanks in advance
Schema:-
module.exports = mongoose => {
const Role = mongoose.model(
"role",
mongoose.Schema(
{
roleType : { type:String },
image: { type: String,
data: Buffer}
}
)
);
return Role;
};
controller (Creating an instance):-
exports.addRoleFields = async (req, res) => {
const rolesList = new Role ({
roleType : req.body.roleType,
roleImg : req.file.path,
});
rolesList
.save(rolesList)
.then(data => {
res.status(200).send({ data, statusCode: "200" });
})
.catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while creating.",
statusCode: "500"
});
})
}
}
routes:-
module.exports = app => {
const multer = require("multer"),
storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'uploads')
},
filename: function(req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
const uploadImg = multer({storage: storage}).single('image');
const roles = require("../controllers/roles.js");
var router = require("express").Router();
router.post("/addRole", uploadImg , roles.addRoleFields);
app.use('/api/roles', router);
};
I simply changed this
filename: function(req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
to
filename: function (req, file, cb) {
cb(null, file.originalname);
}
its working and saving the file
try this for mongodb client
const storage = multer.diskStorage({
destination: async function (req, file, cb) {
let path = 'uploads/' + req.body.path;
if (!fs.existsSync(path)) {
fs.mkdirSync(path, { recursive: true }, (err) => {
if (err) throw err;
});
}
await cb(null, path);
},
filename: function (req, file, cb) {
cb(null, req.body.filename)
}
});
var upload = multer({ storage: storage })
const router = express.Router();
// Upload Image
router.post("/upload", upload.single('image'), (req, res, next) => {
return res.json({
image: req.file.path
});
});
in this upload.single('image'), file should be the name in which formdata carries the file.
in your case,
router.post("/addRole", uploadImg('image'), (req, res)=>{
});
mongoose model
const imgSave = new mongoose.Schema({
img:{
data: Buffer,
contentType: String
}
});

Multer in Node Js

I am trying to use multer module in my website but my doubt is that we are declaring upload as constant const upload =multer({}); but then in the post method, we are using upload (req,res,error) method is it the same object or a different one. Can someone please help me out it would be a great help.
const upload = multer({
storage: storage,
limits:{fileSize: 1000000},
fileFilter: function(req, file, cb){
checkFileType(file, cb);
}
}).single('myImage');`
`app.post('/upload', (req, res) => {
upload(req, res, (err) => {
if(err){
res.render('index', {
msg: err
});
} else {
if(req.file == undefined){
res.render('index', {
msg: 'Error: No File Selected!'
});
} else {
res.render('index', {
msg: 'File Uploaded!',
file: `uploads/${req.file.filename}`
});
}
}
});
});
The upload is defined as object but in the post method we are defining a method

how to make directory first and then upload image on that directory through multer in node js

I want to upload image through multer but first i want to create a directory or folder for every user and then upload the image to that users folder.
If I create a folder for a user myself and upload, passing the user_id, the image is uploaded into that folder.
But if I do it through code, I am not able to do that.
When in destination I am adding req.body.user_id it gives me undefined.
like this :-
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, __dirname + '/images/'+ req.body.user_id)
}
[
app.post('/test', function (req, res) {
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, __dirname + '/images/' )
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now())
//console.log(file);
}
});
var upload = multer({ storage: storage }).single('image');
var formatted = new Date().toLocaleString();
upload(req, res, function (err) {
var data = {
"user_id": req.body.user_id,
"item_id": req.body.item_id,
"sell_type": req.body.sell_type,
"sell_name": req.body.sell_name,
"sell_location": req.body.sell_location,
"sell_price": req.body.sell_price,
"data_post": formatted
};
console.log("error ==>",err);
if(err){
res.status(400).json({
"status_code": 'ERROR',
"message": "image uploadinf Fail"
});
}else{
fs.exists("/var/www/html/Anoop/nodetest/images/" + data.user_id, (exists) => {
console.log(exists);
if(exists) {
res.status(200).json({
"status_code": "SUCCESS",
"message": "uploaded",
"data": req.file.path
});
}
else
{
mkdirp("/var/www/html/Anoop/nodetest/images/" + data.user_id, function (err, result) {
if (err) {
res.status(400).json({
"status_code": "ERROR",
"message": "dir not created"
});
} else {
//console.log(result);
res.status(200).json({
"status_code": "SUCCESS",
"message": "dir created",
"data": req.file.path
});
}
});
}
});
}
});
});
]
Try this code
const fs = require('fs')
const filesDir = 'files';
// check if directory exists
if (!fs.existsSync(filesDir)) {
// if not create directory
fs.mkdirSync(filesDir);
}

Resources