MEAN js download file from system path - angularjs

I want to implement feature in MEANJS project to download mp3 files from system path
Example: /usr/local/setup/file.mp3
I want to apply security checks for valid user and allow user to download mp3 files.
Is there any other way which can be used to download files with security?

We can use below node js function
var path = require('path');
var fs = require('fs');
app.get('/api/download-music', function(req, res){
var filename = "file.mp3";
var filePath = path.join("/usr/local/setup/", filename);
var stat = fs.statSync(filePath);
res.writeHead(200, {
'Content-Type': 'audio/mp3',
'Content-Length': stat.size,
"content-disposition":"attachment; filename="+filename
});
var readStream = fs.createReadStream(filePath);
readStream.on('data', function(data) {
var flushed = res.write(data);
// Pause the read stream when the write stream gets saturated
if(!flushed)
readStream.pause();
});
res.on('drain', function() {
// Resume the read stream when the write stream gets hungry
readStream.resume();
});
readStream.on('end', function() {
readStream
.pipe(res);
});
});
}
in above node js code we can apply security checks with session id.
on angular template we can use below html:
Download

Related

nodejs write simple image blob - Upload.dataUrltoBlob

Simple question. How do I save a image blob in Nodejs from angular.
AngularSide:
$scope.upload = function (dataUrl, picFile) {
Upload.upload({
url: 'http://test.dev:3000/register/user/uploads',
data: {
file: Upload.dataUrltoBlob(dataUrl, picFile.name)
},
}).then(function (response) {
$timeout(function () {
$scope.result = response.data;
});
}, function (response) {
if (response.status > 0) $scope.errorMsg = response.status
+ ': ' + response.data;
}, function (evt) {
$scope.progress = parseInt(100.0 * evt.loaded / evt.total);
});
}
nodejs side: Do I need middleware here? if so which one should I use?
router.post('/user/uploads', multipartMiddleware, function(req, resp) {
var newPath = "/Users/testUser/test_hold_files/" + req.files.file.originalFilename;
fs.writeFile(newPath, req.files.file, function(err) {
if (err) {
console.log("Data Error ");
return console.error(err);
}
});
res.status(200).jsonp({status: "status: success "});
});
right now this just writes out the file with correct name but its empty.
You used to be able to access the uploaded file through req.files.imageName and then you would fs.readFile from tmp and write it permanently, which is no longer the case in express 4.0
In Express 4, req.files is no longer available on the req object by default. To access uploaded files on the req.files object, use multipart-handling middleware like busboy, multer, formidable, multiparty, connect-multiparty, or pez.
Soooooooo, you can feel free to use which ever one of those middlewares names above and then follow their API for dealing with uploaded files like images. Hope this helps, enjoy.
Ok,
After a long time of messing with this stuff. I found an answer. It does load the file in my folder.
I feel this is only partial since it does not resize the actual file smaller. It is what is selected with https://github.com/danialfarid/ng-file-upload. I used the
Upload.upload({
url: 'http://test.dev:3000/register/user/uploads',
data: {
file: Upload.dataUrltoBlob(dataUrl, picFile.name)
},
This did zoom into the file on selected image. It did not make the actual file size smaller. I am still looking into this issue.
var formidable = require('formidable'),
util = require('util'),
fs_extra = require('fs-extra');
This is my post to accept images.
router.post('/user/uploads', function (req, res){
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
res.end(util.inspect({fields: fields, files: files}));
});
form.on('end', function(fields, files) {
/* Temporary location of our uploaded file */
var temp_path = this.openedFiles[0].path;
/* The file name of the uploaded file */
var file_name = this.openedFiles[0].name;
/* Location where we want to copy the uploaded file */
var new_location = "/Users/testUser/test_hold_files/";
fs_extra.copy(temp_path, new_location + file_name, function(err) {
if (err) {
console.error(err);
} else {
console.log("success!")
}
});
});
});
I have also noticed that I can view the file in chrome but not load it into gimp. Gimp gives me a file error.
Small steps I guess.
Maybe Datsik can give us some insight on what is going on here.
https://stackoverflow.com/users/2128168/datsik
Phil

Download only new files on an Ionic app?

I want to download a file from a server only if the file is new. For example, by checking the file modified date. I am using the below code to download the file, but I am stuck where I need to compare the files before downloading. Can anyone please give me a solution for this.
.factory('fileDownloadService',['$cordovaFileTransfer', function($cordovaFileTransfer){
return{
fileDownload:function(){
// File for download
var url = "http://www.xxxxx/file-to-download.json";
// Get file name only
var filename = url.split("/").pop();
// Save location
var targetPath = cordova.file.externalRootDirectory + filename;
$cordovaFileTransfer.download(url, targetPath, {}, true).then(function (result) {
console.log('Download Successful');
}, function (error) {
console.log('Download Error');
}, function (progress) {
// Progress handling
});
}
}}])
Appreciate your help. Thank you

NodeJS/Express4 endpoint generating corrupt xlsx file

I am trying to create an endpoint using NodeJS/express 4 that generates and send to the user a xlsx file.
To create the xlsx file I am using the node-xlsx library.
var xlsx = require('node-xlsx');
var buffer = xlsx.build([{
name: pasta,
data: data
}]);
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
res.setHeader("Content-Disposition", "attachment; filename=" + pasta + ".xlsx");
res.write(buffer, 'binary');
return res.end();
And I am trying to download this file through an Angular app.
$http.post('https://endpoint/v1/' + folderName + '/reportExcel', {
responseType: 'arraybuffer'
})
.success(function(response) {
var blob = new Blob([response], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
var objectUrl = URL.createObjectURL(blob);
$window.open(objectUrl);
However, the file that is being downloaded is broken, so I can not open it.
Could it because you are using connect-livereload plugin? The plugin seems cause corrupted binary files being transferred. I've encountered the same, and solved it by adding 'ignore' when initiate connect-livereload plugin.
app.use(require('connect-livereload')({
ignore:['.xls', '.xlsx']
}));
See this post for detail: https://github.com/intesso/connect-livereload/issues/39
I posted an answer here: https://stackoverflow.com/a/41103999/1623249
Basically, you need to get the buffer from node-xlsx, convert it to base64 and then decode it in the client.

Zip generated by EasyZip is not working properly

I have generated a zip file using Easyzip. I can open it directly from download folder.But when try to open it after downloading, I am getting this error:- 'error occurred while extracting files'.
This my backend code :-
var zip2 = new EasyZip();
zip2.zipFolder('./downloads/'+application._id,function(){
zip2.writeToFile('./downloads/'+application._id+'.zip');
res.setHeader('Content-disposition', 'attachment; filename='+application._id+'.zip');
res.setHeader('Content-type', 'application/zip');
var fs = require('fs');
var filestream = fs.createReadStream('./downloads/'+application._id+'.zip');
filestream.pipe(res);
});
});
My angular.js code
$http.post('/download/archive/' + stateParams._id, {year: year}).success(function (data) {
var file = new Blob([data], {type: 'application/zip'});
console.log(file)
saveAs(file, 'application.zip');
});
Please help me to solve these. Thanks in advance.
I had the same problem and was able to solve it by using:
{responseType:'arraybuffer'} in the $http.post() request.
For more details check: how to download a zip file using angular as well as AngularJS: Display blob (.pdf) in an angular app
Solved issue by using node-native-zip module.
Here is my backend code
var zip = require("node-native-zip");
var files = []
files.push({name:application._id+'.pdf',path:'./downloads/'+vetting_id+application._id+'.pdf'}); //push all the files along with its name and path
var archive = new zip();
archive.addFiles(files, function (err) {
if (err) return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
var buff = archive.toBuffer();
var fs = require('fs');
fs.writeFile('./downloads/'+ vetting._id+'.zip', buff, function () {
console.log("Finished");
var filestream = fs.createReadStream('./downloads/'+vetting._id+'.zip');
filestream.pipe(res);
});

download .zip file from server in nodejs

I am using MEAN, in which I want to allow user to download zip file from server.
So basically I have to do following things:
Create csv files from certain data.
Store that file into some directory.
Compress these file to zip.
When a user clicks on the button, zipped file should be downloaded and readable.
I have achieved 1,2,3 completely, and 4 partially. In this I have been able to successfully download zip file, but this file is in corrupted format and I am not able to read this file.
My code for download functionality is here:
html:
Download CSV Reports
angular part:
$scope.downloadFiles = function() {
$http({
method: 'GET',
url: '/download/csv/files'
}).
success(function(data, status, headers, config) {
var anchor = angular.element('<a/>');
anchor.attr({
href: 'data:attachment' + encodeURI(data),
target: '_blank',
download: 'filename.zip'
})[0].click();
}).
error(function(data, status, headers, config) {
alertify.error(data);
});
};
NodeJS:
var path = require('path'),
fs = require('fs');
exports.downaloadAllCsv = function(req, res) {
var file = 'local path to my zip file',
filename = path.basename(file);
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type:',' application/zip');
var filestream = fs.createReadStream(file);
filestream.pipe(res);
};
I used an npm library called express-zip (found here: https://www.npmjs.com/package/express-zip)
Using Node 4.X and Express 4.X, I can download a zip file from my browser. Getting it to work through Angular is what lead me to my own question:
Client download of a server generated zip file
Given all of that, here is my server code that worked:
Node (4.X) code with express-zip:
router.get('/bulkdownload',function(req,resp){
var titles = req.query.titles || [];
if ( titles.length > 0 ){
utils.getFileLocations(titles).
then(function(files){
let filename = '/tmp/zipfile.zip';
// .zip sets Content-Type and Content-disposition
resp.zip(files,filename);
},
_errorCb)
}
});
The utils.getFileLocations(titles) returns a promise where files is an array like this:
[{path: '/path/to/file/file.abc',name:'file.abc'},{...},{...},...]
My .zip file is not corrupted, and is readable.

Resources