Getting mkdir error while using uploading image using multer - node.js

while uploading file and creating a path , I am getting creating a folder error :-
Error: EACCES: permission denied, mkdir '/opt/bitnami/apps/NodeJS-Login/uploads'
at Object.fs.mkdirSync (fs.js:885:18)
at Function.sync (/opt/bitnami/apps/NodeJS-Login/node_modules/mkdirp/index.js:71:13)
at new DiskStorage (/opt/bitnami/apps/NodeJS-Login/node_modules/multer/storage/disk.js:21:12)
at module.exports (/opt/bitnami/apps/NodeJS-Login/node_modules/multer/storage/disk.js:65:10)
at new Multer (/opt/bitnami/apps/NodeJS-Login/node_modules/multer/index.js:15:20)
I am using bitnami on AWS to host my MEAN app.
on my main server.js file I have added this:-
app.use(multer({ dest: './uploads/',
rename: function (fieldname, filename) {
return filename;
},
}));
on schema model :-
companyLogo: {
data: Buffer,
type: String
}
and in controller for route :-
admin.companyLogo = fs.readFileSync(req.files.comLogo.path)
admin.companyLogo.type = 'image/png';
What should I do to make image upload ? Also do I have to pass other key values in form-data instead of raw ?

/opt is write protected by default, so here are possible fixes
1) Change permissions for /opt and allow the user to write in this folder (Not Recommended)
OR
2) Run the server.js with the super user, this way you have complete right over the directory and it will allow you to do anything (Not Recommended)
OR
3) Just change the path to somewhere the user has access to write (Recommended)

Related

How to download files in azure blob storage into local folder using node js

I am using node js to download azure blob storage files into our local machine. I am able to download it into my project path but not able to download into my local machine. I am using html, Express,and node js. Currently working on localhost only. How to download ?
Below is the code that i am using to download blob file to local folder.
app.get("/downloadImage", function (req, res) {
var fileName = req.query.fileName;
var downloadedImageName = util.format('CopyOf%s', fileName);
blobService.getBlobToLocalFile(containerName, fileName, downloadedImageName, function (error, serverBlob) {
});
});
I am able to to download it to my project folder but i want to download it to my downloads folder. Please help me on this ?
To download a file from Azure blob storage
ConnectionString: Connection string to blob storage
blobContainer: Blob Container Name
sourceFile: Name of file in container i.e sample-file.zip
destinationFilePath: Path to save file i.e ${appRoot}/download/${sourceFile}
const azure = require('azure-storage');
async function downloadFromBlob(
connectionString,
blobContainer,
sourceFile,
destinationFilePath,
) {
logger.info('Downloading file from blob');
const blobService = azure.createBlobService(connectionString);
const blobName = blobContainer;
return new Promise((resolve, reject) => {
blobService.getBlobToLocalFile(blobName, sourceFile, destinationFilePath, (error, serverBlob) => {
if (!error) {
logger.info(`File downloaded successfully. ${destinationFilePath}`);
resolve(serverBlob);
}
logger.info(`An error occured while downloading a file. ${error}`);
reject(serverBlob);
});
});
};
According to the reference of the method blobService.getBlobToLocalFile, as below, the value of parameter localFileName should be the local file path with related dir path.
localFileName string The local path to the file to be downloaded.
So I created a directory named downloadImages and changed your code as below.
var downloadDirPath = 'downloadImages'; // Or the absolute dir path like `D:/downloadImages`
app.get("/downloadImage", function (req, res) {
var fileName = req.query.fileName;
var downloadedImageName = util.format('%s/CopyOf%s', path, fileName);
blobService.getBlobToLocalFile(containerName, fileName, downloadedImageName, function (error, serverBlob) {
});
});
It works for me, the image file was downloaded into my downloadImages directory, not under the path of my node app.js running.
Note: If you want to deploy it on Azure WebApp later, please must use the absolute directory path like D:/home/site/wwwroot/<your defined directory for downloading images>, because the related directory path is always related the path of IIS started up node.

express fileupload : no such file or directory

I am using express-file package. I use it like this:
const upload = require('express-fileupload');
app.use(upload({
createParentPath: true
}));
This is how I store:
await req.files.main_image.mv('./public/images/movies/'+main_image);
I already have public/images directory created. I don't have movies directory in public/images directory though.
When It works: If I have /public/images/movies directory already created, it works
When it doesn't work: If I don't have /public/images/movies directory created, but have /public/images directory. Then it says:
ENOENT: no such file or directory, open
'C:\Users\glagh\Desktop\Work\MoviesAdviser\public\images\movies\1554741546720-8485.11521.brussels.the-hotel-brussels.amenity.restaurant-AD3WAP2L-13000-853x480.jpeg
What to do so that it automatically creates /movies directory and put the image there?
Express-fileupload uses the following code to create the directory-path which you pass to the .mv function:
const checkAndMakeDir = function(fileUploadOptions, filePath){
//Check upload options were set.
if (!fileUploadOptions) return false;
if (!fileUploadOptions.createParentPath) return false;
//Check whether folder for the file exists.
if (!filePath) return false;
const parentPath = path.dirname(filePath);
//Create folder if it is not exists.
if (!fs.existsSync(parentPath)) fs.mkdirSync(parentPath);
return true;
};
The problem is that fs.mkdirSync() does not create the full path with the parent directories you specifiy (note that you'd use mkdir -p on the shell to create the whole folder structure) -> checkout How to create full path with node's fs.mkdirSync? for more information.
What you could do is use a module like fs-extra and use its function ensureDir which would create the corresponding parent directories (if they don't exist yet) before calling the .mv() function.
Or in case you're node version is >= 10 use the native {rescursive:true} option which you can pass to fs.mkdirSync.

how to upload image to backblaze using hapijs

I am trying to upload image to backblaze-b2 using hapi.js. I am using a plugin called easy-backblaze but while using it I need to mention the path of the file. But While importing the file using Hapijs I am not able to understand how to get that path.
This is the Code I have written and here in b2.uploadFile I need to mention the path of the file on local Drive:
var B2 = require('easy-backblaze');
var b2 = new B2('accountId', 'applicationKey');
b2.uploadFile('C:/Users/Lovika/Desktop/addDriver.png', {
name: 'addDriver.png', // Optional, renames file
bucket: 'testBucket', // Optional, defaults to first bucket
}, function(err, res) {
console.log('Done!', err, res);
});
Do I need to upload the file to the server first and then to backblaze or Is there any way to upload the file directly to backblaze

node.js pulling file form S3 to local

Currently i am trying to load a file from S3 into my temp file. i am using Node.js running on lambda.
Here is the code i am trying to use
var options = {
Bucket: 'my_bucket',
Key: dstKey
};
var input = './temp.pdf';
var file = require('fs').createWriteStream(input);
s3.getObject(options).createReadStream().pipe(file);
I have also tried using the __dirname in my input path with the same results.
I keep getting a file write error.
2016-06-14T19:31:02.859Z 5ea0381c-3266-11e6-a2e3-312b48485905 Error: EACCES: permission denied, open './temp.pdf' at Error (native)

Use Cordova's Filetransfer plugin with express/blob storage

I am using Typescript and Cordova 4.0.
I have the following sample code:
uploadImages(imageUris: Array<string>): any {
var fileTransfer = new FileTransfer();
for (var i = 0; i < imageUris.length; i++) {
fileTransfer.upload(imageUris[i], encodeURI('http://3187cf3.ngrok.com/test/photos'), (success) => {
alert('success');
}, (err) => {
alert('error');
});
}
}
This corresponds to an express route:
var router = express.Router(),
test = test.controller;
router
.post('/test/photos', bind(test.uploadPhotos, test));
Which corresponds to a controller method:
uploadPhotos(req: express.Request, res: express.Response) {
console.log(req);
}
I can't seem to figure out how to, inside of my controller, grab the "file" or image I'm posting to my server using Filetransfer. It's not on req.body or req.query, and when I look through the entire req I can't seem to locate the file. The app flow is working enough to actually make the POST request to test/photos, I just don't know how to or if I can access the file at that point.
How does Filetransfer work, and how can I access the data I need in my controller so that I can push it to Azure Blob Storage?
It looks like you have everything setup correctly to send the data through to your controller. The issue is that you need to put the file on the request since cordova's filetransfer plugin doesn't do that by default.
You can do that with a popular library multer.
npm install multer --save-dev To install multer and save it to your package.json file.
In your express config file, add something like the following:
var multer = require('multer');
app.use(multer({ dest: path.resolve(config.root, 'public/img/') }))
'public/img/' is the path you would like for your image to be saved.
Now your req will have files on it. To upload a single file, you would use req.files.file. You'll want to use this variable to send your file to azure's blob storage using something like blobSvc.createBlockBlobFromLocalFile(containerName, fileName, filePath)
Since you're using Azure for remote storage, chances are you will want to remove the local file that multer has saved. I'd recommend using fs or rimraf to remove the file stored in public/img/, or whatever you set the path to in your express config. If you are using fs, you'll want to use the .unlink command.

Resources