Change filename with multer NodeJs - javascript

I have to upload a file which the name depends of a varible sended to the request. So I have a variable declared, imageType, to use in the multer.diskStoragean I have another variable for de dynamic path too, imagePath which it's working in the same way that I'm using the imageType, but I'm getting undefined-logo.jpg from the imageType. Here is the code:
var imagePath = '';
var imageType = '';
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, imagePath);
},
filename: function (req, file, callback) {
callback(null, (imageType + '-logo.jpg'));
}
});
var upload = multer({ storage: storage }).single('file');
router.route('/representatives/:id/loginLogo')
.post((req, res, next) => {
/////SOME CODE BEFORE/////
if (rows[0].client_directory == '') {
imagePath = `${rows[0].subdomain_directory}`;
} else {
imagePath = `${rows[0].subdomain_directory}/${rows[0].client_directory}/`;
}
imageType = req.body.imageType;
upload(req, res, function (err) {
if (err) {
return next(err);
}
var sql = `UPDATE representatives SET login_logo = 'jpg' WHERE id = ${req.params.id}`;
conn.query(sql, (err, rows, fields) => {
if (err) {
return next(err);
}
res.json({ message: 'Image uploaded!', representative: req.body.imageType}); //HERE RETURNS req.body.imageType OK
})
})
})
Could you help me? Thanks!

Related

What is the correct way to make multer work with Node and Express here?

I am trying to create a route through which I can upload photos. However as I made so,e changes it stopped working and I am not sure how to make it work.
const multer = require('multer');
// MULTER STORAGE
const multerStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, '/upload');
},
filename: (req, file, cb) => {
const ext = file.mimetype.split('/')[1];
// Saving format: user-UserId-DateStamp.ext
//e.g user-608d55c7e512b74ee00791de-1621992912638.jpeg
cb(null, `user-${req.body.userId}-${Date.now()}.${ext}`);
},
});
//MULTER FILTER
const multerFilter = (req, file, cb) => {
//mimetype always starts with image/ then png or jpeg or..
if (file.mimetype.startsWith('image')) {
cb(null, true);
} else {
cb(new AppError('You are only allowed to upload image files.', 400), false);
}
};
const uploadDirectory = multer({
storage: multerStorage,
fileFilter: multerFilter,
});
//exports.uploadPhoto = uploadDirectory.single('photo');
//app.use(express.static('./uploads'));
// INCLUDE ERROR CLASS AND ERROR CONTROLLER
const AppError = require('../utils/appError.js');
const errorController = require('./errorController.js');
const { Mongoose } = require('mongoose');
The main problem Im guessing is in this block
//UPLOAD PHOTO
exports.uploadPhoto = uploadDirectory(async (req, res) => {
console.log(req.body);
console.log(req.file);
try {
const newPhoto = await photoModel.create(req.file);
newPhoto.save().then((result) => {
console.log('Saved');
res.status(201).json({
status: 'success',
// data: JSON.parse(JSON.stringify(newPhoto.file)),
});
});
} catch (err) {
console.log('Error in upload');
errorController.sendError(err, req, res);
}
}).single('photo');
Can anybody let me know how to correctly write the exports.uploadPhoto
Originally the last function looked like this
exports.uploadPhoto = async (req, res) => {
console.log(req.body);
console.log(req.file);
try {
const newPhoto = await photoModel.create(req.file);
newPhoto.save().then((result) => {
console.log('Saved');
res.status(201).json({
status: 'success',
// data: JSON.parse(JSON.stringify(newPhoto.file)),
});
});
} catch (err) {
console.log('Error in upload');
errorController.sendError(err, req, res);
}
};
The multer middleware function, in your case uploadDirectory, is usually used before other middleware functions/controllers where you have your business logic (e.g. uploadPhoto).
app.post('/upload', uploadDirectory.single('photo'), uploadPhoto);
Keep your original uploadPhoto function and with the above code you'll have access to the data and file through reg.body and req.file, respectively.
This Request Parsing in Node.js Guide (it's free) will help you with file uploads in Node.js.

Req,File.Path remains undefined and i am using multer due to vague documentation,i cannot fully understant it?

I,m using mutler to upload a image and i am constantly getting this error.
And i think the following function triggers it.
The complete js code is attached below.Thanks in advance!
const upload = multer({
dest: "/uploads"
});
app.post(
"/game",
upload.single("file" /* name attribute of <file> element in your form */),
(req, res) => {
const tempPath = req.file.Path;
const targetPath = path.join(__dirname, "/uploads/"+imgname+".jpg");
imgname++;
if (path.extname(req.file.originalname).toLowerCase() === ".jpg") {
fs.rename(tempPath, targetPath, err => {
if (err) return handleError(err, res);
res
.status(200)
.sendFile(__dirname + '/game.html');
});
} else {
fs.unlink(tempPath, err => {
if (err) return handleError(err, res);
res
.status(403)
.contentType("text/plain")
.end("Only .jpg files are allowed!");
});
}
}
);
Js file link: https://filebin.net/fd7q89ji16xftst4
Your code doesn't have a variable called imgname. After checking the code, it looks like you need to pass the file name for the imgname. You can use req.file.filename to get the name of the uploaded file.
Full code:
const upload = multer({
dest: "/uploads"
});
app.post(
"/game",
upload.single("file" /* name attribute of <file> element in your form */),
(req, res) => {
const tempPath = req.file.Path;
const imgname = req.file.filename;
const targetPath = path.join(__dirname, "/uploads/"+imgname);
imgname++;
if (path.extname(req.file.originalname).toLowerCase() === ".jpg") {
fs.rename(tempPath, targetPath, err => {
if (err) return handleError(err, res);
res
.status(200)
.sendFile(__dirname + '/game.html');
});
} else {
fs.unlink(tempPath, err => {
if (err) return handleError(err, res);
res
.status(403)
.contentType("text/plain")
.end("Only .jpg files are allowed!");
});
}
}
);

How to read stored file using Multer disk storage option (NodeJs)?

I am able to store images in my local disk storage using multer successfully but while using GET method, it throws "Cannot GET /uploads/image-1547436792386" error. I have provided my image-upload.js code below:
const multer = require('multer');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/');
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now());
}
});
const upload = multer({ storage: storage });
module.exports = upload;
Service.ts:
const imageUpload = require('../services/image-upload');
const singleUpload = imageUpload.single('image');
module.exports = function(app) {
app.post('/api/image-upload', auth.jwtRefreshToken, imageUploadRoute);
};
function imageUploadRoute(req, res) {
const userId = req.userId;
if (typeof userId !== 'string') {
return res.status(422).json({message: 'Error in UserId'});
}
singleUpload(req, res, function(err) {
if (err) {
return res.status(422).send({errors: [{title: 'Image Upload error', detail: err.message}]});
}
User.findOne({_id: userId})
.then((user) => {
console.log(req.file);
user.profileImage = req.file.path;
return user.save()
.then(() => {
return res.status(200).send({message: 'Image Uploaded Successfully'});
})
.catch(() => {
return res.status(500).send({message: 'Error in uploading image'});
});
})
.catch(() => {
return res.status(500).send({message: 'UserId not found'});
});
});
}
Where is your GET API implementation?.Anyway, below code worked for me to download the files. Please try this.
app.get("/download/:name(*)", function (req, res, next) {
var file = req.params.name;
var path = '/yourFileLocation' + '/' + file;
res.download(path, file, function (err) {
if (err) {
res.status(500).send({ "error": 'Unexpected error occured.' });
} else {
res.send({ "message": 'success' });
}
});
});

Encrypt the uploaded file before saving to disk using Node.js

Currently, I am using multer library to save files on File system. This application is using Node and Express.
I can save the file first on server and then encrypt it. Later on delete the unencrypted file. However, I do not want to add unencrypted file on server directly. So, I am looking for a way to encrypt the incoming file from the front end and then save it to disk.
const defaultFolder = 'upload';
const filePath = resolveHome(process.env.FILE_STORAGE_LOCATION || defaultFolder);
const key = 'test';
const cipher = crypto.createCipher('aes-256-cbc', key);
const decipher = crypto.createDecipher('aes-256-cbc', key);
const upload = multer({
storage: multer.diskStorage({
destination: filePath,
filename: (req, file, cb) => {
const parts = file.originalname.split('.');
const ext = parts.pop();
const name = parts.join('.');
cb(null, name + '-' + Date.now() + '.' + ext);
},
}),
}).single('file');
app.post('/upload', (req, res) => {
upload(req, res, err => {
if (err) {
return res.status(400).send({
error: 'The request was invalid',
fileName: req.file.originalname,
});
}
return res.status(200).send({
fileName: req.file.filename,
});
});
});
I tried to use crypto library to encrypt the file but it's not working. I believe the req.cipher is invalid as I would normally use req.file to get reference to the file.
app.post('/upload', (req, res) => {
upload(req, res, err => {
output = fs.createWriteStream(filePath + '/' + req.file.originalname);
req.pipe(cipher).pipe(output).on('finish', () => console.log('Encrypted file written on disk'));
if (err) {
return res.status(400).send({
error: 'The request was invalid',
fileName: req.file.originalname,
});
}
return res.status(200).send({
fileName: req.file.originalname,
});
});
});
I had tried to just write file without using cipher and file was empty. Adding this information in case it helps.
req.pipe(output).on('finish', () => console.log('Encrypted file written on disk'));
Can you try this
app.post('/upload', function(req, res) {
upload(req, res, function(err) {
var fileName = req.file.destination +"\\"+ req.file.filename
var input = fs.createReadStream(fileName);
var output = fs.createWriteStream(fileName + ".enc");
input.pipe(cipher).pipe(output);
output.on('finish', function() {
fs.unlink(fileName, (err) => {
if (err) throw err;
console.log('Encrypted file written to disk!');
res.end('Encrypted file written to disk!')
});
});
})
})

Uploading image to Multer on Node JS server from Xamarin C# app

I'm trying to upload an image to a Node JS from a PCL Xamarin forms library. I've tried using the Multer Node JS library to pick up the the POST request. The request is received, however the photo is not saved. The file is always 'undefined'.
Node JS code:
var formidable = require('formidable');
var util = require('util');
var fs = require('fs');
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './photouploads');
},
filename: function (req, file, callback) {
console.log(file.fieldname);
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage: storage }).single('image');
exports.post = function (req, res) {
console.log("Photo Api Hit");
upload(req, res, function (err) {
console.log(req.file);
if (err) {
console.log("error");
console.log(err);
return res.end("Error uploading file.");
}
console.log("File has been received");
res.end("File is uploaded");
});
};
C#/Xamarin Code
using Plugin.Media.Abstractions;
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
namespace Vigour.Controllers
{
class MediaController
{
public static void upload(MediaFile mediaFile)
{
try
{
StreamContent scontent = new StreamContent(mediaFile.GetStream());
scontent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = "newimage",
Name = "image"
};
scontent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var client = new HttpClient();
client.BaseAddress = new Uri(Constants.API_ROOT_URL);
var result = client.PostAsync("api/photo", scontent).Result;
Debug.WriteLine(result.ReasonPhrase);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
}
}
Does anyone know how the request should be formed in my C# code? Thanks
I found that using this method was effective for a PCL
The MediaFile is an object from the Xamarin.Plugins.Media Library
public static void upload(MediaFile mediaFile)
{
try
{
StreamContent scontent = new StreamContent(mediaFile.GetStream());
scontent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = "newimage",
Name = "image"
};
scontent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var client = new HttpClient();
var multi = new MultipartFormDataContent();
multi.Add(scontent);
client.BaseAddress = new Uri(Constants.API_ROOT_URL);
var result = client.PostAsync("api/photo", multi).Result;
Debug.WriteLine(result.ReasonPhrase);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
I used node js (hosted on azure) to receive the request.
var formidable = require('formidable');
var util = require('util');
var fs = require('fs');
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
console.log(file.fieldname);
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage: storage }).single('image');
exports.post = function (req, res) {
console.log("Photo Api Hit");
upload(req, res, function (err) {
console.log(req.file);
if (err) {
console.log("Photo API ERROR: "+err);
return res.end("Error uploading file.");
}
console.log("SUCCESS");
res.end("File is uploaded");
});
};

Categories

Resources