Download file with app.get problem

NodeBB Plugins
  • Hello !

    I have a file (among others) in a specific folder outside of nodebb (for example /toto/myfiles/filetoget ; nodebb executable is in /toto/nodebb folder).

    I want to be able to download the /toto/myfiles/filetoget file with the route "/myfiles/filetoget". For this, I use the following code (in the static:app.load hook) in a plugin :

    app.get('/myfiles/:file(*?)', function (req, res) {
                    // absolute path to the file to get
    		var absolutefile = path.dirname(process.cwd()) + '/myfiles/' + req.params.file;
    
    		if (fs.existsSync(absolutefile)) {
    			res.status(200);
    			res.sendFile(absolutefile);
    		} else {
    			console.log('File not found');
    			res.status(404);
    			res.render('404', {path: req.path});
    		}
    });
    

    It works when I full load page http://127.0.0.1:4567/myfiles/filetoget but it doesn't work when I click on a link with 'myfiles/filetoget' (showing also the full address http://127.0.0.1:4567/myfiles/filetoget on a nodebb page). I have a page of nodebb saying the page is not found and there is no particular message in the console.

    How can I solve this problem ? (I do this because I will do other things (permissions...) before the download of the file in my plugin).

    I will also link these files in admin/manage/categories/** as external link (I hope it's possible)...

    If I use a wrong way, how can I make relative links (routes) in nodebb to files outer from nodebb folder ?

    Thanks in advance for help !

  • NodeBB probably treats that url like a normal page since it doesn't start with /uploads or /assets/uploads and it tries to ajaxify to that page. https://github.com/NodeBB/NodeBB/blob/master/public/src/ajaxify.js#L395

    You also have to be careful with allowing access to the filesystem and make sure users can only download from the myfiles folder. Ie if someone manages to pass in req.params.file = ../nodebb/config.json they might download your config.json file.

  • @baris said in Download file with app.get problem:

    NodeBB probably treats that url like a normal page since it doesn't start with /uploads or /assets/uploads and it tries to ajaxify to that page. https://github.com/NodeBB/NodeBB/blob/master/public/src/ajaxify.js#L395

    So is there a way to prevent this or another way to do what I want ? I need to make links to files that are not in nodebb folder (I don't want users to be able to directly download them like when they are in public/uploads because I will check some specific permissions before...). Note also that files will change so it must work without restarting nodebb...

    You also have to be careful with allowing access to the filesystem and make sure users can only download from the myfiles folder. Ie if someone manages to pass in req.params.file = ../nodebb/config.json they might download your config.json file.

    Yes. It will be a part of my plugin.

  • I would look into using express.static to mount a directory and have it accessible as a route.

  • @julian said in Download file with app.get problem:

    I would look into using express.static to mount a directory and have it accessible as a route.

    I will give it a try but will it prevent the ajaxify problem raised by @baris at the begining of its answer ?

    Also, files will not be public ? I want to serve files only after tests of permissions...

  • Finally, I made it simpler...

    I made a link from /toto/myfiles to public/uploads/myfiles. Then, I wrote this app.get code in my plugin :

    app.get('/uploads/myfiles/:file(*?)', function (req, res) {
    		// Things TODO with req.params.file for permissions (after work on it)...
    		var longfilename = path.resolve('public' + req.url);
    		if (fs.existsSync(longfilename)) {
    			res.status(200);
    			res.sendFile(longfilename);
    		} else {
    			console.log('Fichier non trouvé');
    			res.status(404);
    			res.render('404', {path: req.path});
    		}
    	});
    

    Now, there is no problem with the ajaxify thing... Ouf !

    I'm going to open another topic for another question about the 404 error rendering... 😉


Suggested Topics


  • 0 Votes
    3 Posts
    446 Views

    @benjamin-liehr

    Add custom Page, f.e. start
    eada19d2-1c3f-4a27-bc1a-28ece546cfd8-image.png

    Choose this Page from Settings:
    dce8064d-0130-4dc6-a010-fb59ffc710d6-image.png

    Modify the Page template from Extend->Widgets:
    9bc6fd05-4a81-4f7c-845d-dd417810c3cc-image.png

    Save, and voila:
    16054c31-dff0-463b-904e-0ef76c427935-image.png

  • 1 Votes
    7 Posts
    2k Views

    Those hooks weren't working the way they were meant to, that's why they are deprecated. If you need to do a one time operation when the plugin is installed. Just set a flag in the database stating that the operation is done so it is not repeated on every restart of NodeBB.

  • 0 Votes
    6 Posts
    2k Views

    @baris and in the version like 1.2.1 how I can do ( I can't upgrade to 1.3.0) ? Because if I use 👍

    db.getSortedSetRevRange('uid:' + uid_of_user + ':bookmarks', 0, -1, callback);

    It's not work in the 1.2.1 maybe I can use:

    db.getSortedSetRange('uid:'+uid+":favourites",callback);?
  • 0 Votes
    4 Posts
    2k Views

    This is now on master. The data that is passed to the filter includes the topic, the uid of the current user and an empty tools array.

  • 0 Votes
    2 Posts
    2k Views

    @DanaGriffin said:

    As the title suggest, I am trying to allow my users to upload documents on the forum. Are there any plugins to do so, or is this something I will have to implement myself? Thanks for your patience.

    You could allow local uploading and specify a file size, go to Settings > Post > Tick Allow Users to Upload Regular Files, then adjust the file size from the default 2mb to whatever you feel you need.

    This will give you a new icon on the composer. I've just tested it with a pdf and it works fine.