swarajd
swarajd

Reputation: 1007

express.js unique directory for each user

I have an express.js app, and I am using drywall in order to manage the user system.

When a user signs up, I want a directory to be generated for that user, and I want that user to be able to upload files to that directory and view those files through his or her account.

I am not entirely sure, but I think that most likely for the directory generation I will have to do that inside views/signup/index.js, and that the user can only upload files to his or her directory if logged in.

However, I'm a bit stuck when it comes to saving and displaying the files. I have little experience with server side code, so implementing actions such as accessing files is slightly beyond my scope.

Thanks in advance to those who help.

Upvotes: 1

Views: 585

Answers (1)

alessioalex
alessioalex

Reputation: 63663

So first you should create a folder for each user by using fs.mkdir:

http://nodejs.org/api/fs.html#fs_fs_mkdir_path_mode_callback

Let's say you want to create these folders into your app root / images:

Example:

var fs = require('fs');
fs.mkdir(__dirname + '/images/' + userId, function(err) {
  if (err) {
    /* log err etc */
  } else { 
    /* folder creation succeeded */
  }
});

You should probably use the userId for the folder name (since it's easier than trying to strip out the bad characters from the username itself, and this will also work in the future if the user changes his username).

The second thing you need to do is to allow the user to upload files (but only if he is logged in and into the right folder). It's better to not include the bodyParser middleware for all routes, but instead include the json && urlencoded middleware for all routes (http://www.senchalabs.org/connect/json.html && http://www.senchalabs.org/connect/urlencoded.html) and the multipart middleware only for the upload url ( http://www.senchalabs.org/connect/multipart.html && example: https://github.com/visionmedia/express/blob/master/examples/multipart/index.js ).

An example:

app.post('/images', express.multipart({ uploadDir: '/tmp/uploads' }), function(req, res, next) {
  // at this point the file has been saved to the tmp path and we need to move
  // it to the user's folder
  fs.rename(req.files.image.path, __dirname + '/images/' + req.userId + '/' + req.files.image.name, function(err) {
    if (err) return next(err);

    res.send('Upload successful');
  });
});

Note: in the example above I've taken into consideration that req.userId is populated with the id of the user by an auth middleware.

Showing the images to the user if he has the rights to see them (the auth middleware should be applied for this path as well):

app.get('/images/:user/:file', function(req, res, next) {
  var filePath = __dirname + '/images/' + req.userId + '/' + req.params.file;

  fs.exists(filePath, function(exists) {
    if (!exists) { return res.status(404).send('Not Found'); }

    // didn't attach 'error' handler here, but you should do that with streams always
    fs.createReadStream(filePath).pipe(res);
  });
});

Note: in production you might want to use send instead, that example was just demoing the flow ( https://github.com/visionmedia/send ).

Upvotes: 1

Related Questions