Home > database >  How to res.sendFile whilst res.rendering an HTML that uses the sent file in Express.js?
How to res.sendFile whilst res.rendering an HTML that uses the sent file in Express.js?

Time:05-12

I am trying to create a file server that use node.js and Express. I have the system currently set up so that each user has a file directory. I currently have it set so that the whole file system is hosted using

app.use(express.static(testFolder));

The problem with this approach is that anyone could view anyones files even if they are not logged in. I have looked and other people recommend to not host the whole file system and use res.sendFile(specific file) instead. People also recommend to use middleware to check that the user is authenticated.

My problem with this is that, say for photos, I have a photos route and EJS file set up so that for all photos, the photo that is to be viewed is rendered inside the .ejs file.

How would I res.sendFile() but then have it rendered inside a .ejs file? As just res.sendFile() only shows the photo with a white background and no customisation.

Here is the code for the route:

router.post("/view/photo", function(req, res){
    var path = req.body.currentPath
    var filename = req.body.fileName
    var currentUser = req.body.currentUser
   
    var files = fs.readdirSync(path)
    var images = []
    var fileExtensions = ['jpg', 'jpeg', 'gif', 'png']

    for(var i = 0; i < files.length; i  ){
        fileExtension = files[i].split(".")[1]
        if(fileExtension){
            if(fileExtensions.includes(fileExtension.toLowerCase())){
                images.push(files[i])
            }
        }
    }
 
    var indexOfFile = images.indexOf(filename)
    var next = indexOfFile   1;
    var previous = indexOfFile - 1;

    if(next > images.length - 1){
        next = next - (images.length)
    }
    if(previous < 0){
        previous = previous   (images.length)
    }

    path = path.split("/")
    path = path.splice(path.indexOf(currentUser, 0), path.length)
    path = path.join("/")
    finalPath = "../"   path   "/"   filename
    
    var nextFileName = images[next]
    var prevFileName = images[previous]

    res.sendFile(req.body.currentPath   "/"   filename);

    // res.render("showPhoto.ejs", {photoPath: finalPath, filename: filename, currentPath: req.body.currentPath, next: nextFileName, prev:prevFileName });  
})

CodePudding user response:

Forget about replacing express.static with sendFile. That's a red herring.

If you want to allow only authenticated users to see an anything, then add middleware that checks to see if they are authenticated on the route that serves up whatever the anything is.

It doesn't matter how the route serves up the anything, only that you authenticate the user before doing do.

If the route uses static to serve up an image file, then add some authentication middleware before it. If the route uses render to generate an HTML document which includes an <img> that points to the previously mentioned static route, then add some authentication middleware before it. etc.

router.post(
    "/view/photo",
    authenticationMiddleware,
    photoPostingEndpointFunction
);

router.use(
    "/photos",
    authenticationMiddleware,
    express.static('path/to/protected/photos)
);
  • Related