What steps can be taken to verify if the userID retrieved from req.user in Passport JS matches the userID in MongoDB before making any updates or deletions

Currently, I am developing a voting application that includes a feature for authenticated users to delete and edit their own polls using Passport JS authentication.

My Passport setup with Node/Express looks like this:

 passport.use(new FacebookStrategy({ 

  clientID: FACEBOOK_APP_ID,
  clientSecret: FACEBOOK_APP_SECRET,
  callbackURL: CALLBACK_URL

}, function(accessToken, refreshToken, profile, done){  
//callback function after login  

  process.nextTick(function(){        
    done(null, profile);        
  });      
}));


passport.serializeUser(function(user,done){

req.session.passport.user = {};  

  done(null, user);

});

passport.deserializeUser(function(id, done){

  done(null, id);

});


app.get('/auth/facebook', passport.authenticate('facebook'));


app.get('/auth/facebook/callback', passport.authenticate('facebook', { 
    successRedirect: '/',
    failureRedirect: '/error'

}));

app.get('/success', function(req, res, next) { 

  res.send('Successfully logged in. You can close this window');      
});


app.get('/error', function(req, res, next) {    
  res.send("Error logging in.");      
});

Hence, every request now carries the user information (req.user) including the id and displayName

To secure a route server-side, I utilize the following middleware function:

var auth = function(req,res,next){

    if(!req.isAuthenticated()){

      console.log("You need to login!");

      res.sendStatus(401);                    
    } 
    else {

      console.log("User is logged in, success!");          
      next();          
    }              
};

The format used for storing polls in MongoDB is as follows:

{
    "_id": {
        "$oid": "57c69ec65ed24f166b4e98cf"
    },
    "title": "Poll Test",
    "options": [
        {
            "option": "Option1",
            "votes": 0
        },
        {
            "option": "Option2",
            "votes": 0
        },
        {
            "option": "Option3",
            "votes": 0
        },
        {
            "option": "Option4",
            "votes": 0
        }
    ],
    "userID": "1798846357",
    "displayName": "John Doe",
    "date": "Wed Aug 31 2016 09:09:26 GMT+0000 (UTC)"
}

In order to protect a specific route in my REST API, particularly for actions like deleting a poll from the front-end, it's important to validate if the user requesting is not only authenticated but also owns the poll. However, implementing this check by comparing the userID in the request with the one in the database has been challenging.

I attempted to incorporate an if statement within the db.collection function to verify if req.user.id and doc.data.id align, but encountered difficulties due to the timing of updateOne.

If you have any insights on how to retrieve the poll based on userID and verify its match with req.user.id before proceeding with the update, please share your thoughts!

    app.delete("/polls/:id", auth, function(req, res) {         
    db.collection(POLLS_COLLECTION).deleteOne({
      _id: new ObjectID(req.params.id)
    }, function(err, doc) {

      if (err) {

        handleError(res, err.message, "Failed to delete contact");

      } else {

        res.status(204).end();
      }    
    });        
  });        
});

Answer №1

Perhaps this solution can assist you:

Solution to the inquiry:

Is there a way to fetch the poll using the userID and then verify it with the req.user.id before proceeding with the update?

db.collectionName.updateOne({userID :  req.user.id}, {updateQuery});

The provided query will only update the document if there is an existing one with a matching userID as the value of req.user.id. Otherwise, no updates will be made.

We trust that this information proves helpful.

Answer №2

To ensure data integrity, it is important to utilize the filter parameter of either deleteOne or updateOne:

db.collection(POLLS_COLLECTION).deleteOne({
      _id: new ObjectID(req.params.id),
      userID: req.user._id,
    }, function(err, doc) {
    …
    });
  });

If you choose to first retrieve the vote object and use .then for deletion based on conditions, be cautious of concurrency issues without implementing write locks. Altering the userID of the vote object between checks could lead to unexpected outcomes - how will you handle such a scenario?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are the steps to integrate Webpack into an EJS Reactjs Express MongoDb application?

I have incorporated EJS, Express/NodeJs, and MongoDB into the project, along with ReactJs as an addition. My next step is to introduce Webpack for bundling both EJS and ReactJs files together. Although the end goal is to transition the p ...

Setting up Node and NPM on Laradock can streamline your development

After carefully following the steps outlined in the documentation to enable NPM on my workspace, I encountered an issue. Upon running docker-compose exec workspace bash and checking for node -v, it was not installed as expected. The document does not pro ...

Detecting answering machines with Twilio

Hello, I work as a firmware developer at a startup based in Paris. Currently, we are incorporating Twilio into our product and facing an issue with stopping calls to voice machines using the IfMachine parameter. Despite our efforts, we have not been succes ...

Error: JSON parsing error at position 0, caused by an unexpected token "<", originating from devtools shell.js

I am in the process of developing a desktop application using Electron.js and Express.js Upon initial loading, I encountered a warning that stated: SyntaxError: Unexpected token < in JSON at position 0", source: devtools://devtools/bundled/shell.j ...

Am I going too deep with nesting in JavaScript's Async/Await?

In the process of building my React App (although the specific technology is not crucial to this discussion), I have encountered a situation involving three asynchronous functions, which I will refer to as func1, func2, and func3. Here is a general outline ...

Guide to setting up Firebase Admin to initialize application based on request environment

Currently working on a React Native application with 3 variants: development, staging, and production. I only have two Firebase projects, one for production and the other for development/staging purposes. I have an Express server that utilizes the Firebas ...

eliminating any occurrences of a particular character and symbol within a string

Can someone please help me figure out the most effective way to eliminate all occurrences of \n in a string using javascript? I attempted mystring = mystring.replace(/\n/g,''); ...

Using CKEditor in an AngularJS web application: Tips and tricks

I'm having trouble integrating the ckeditor into an HTML page that's built with angularjs. Despite trying out numerous examples, such as the ng-ckeditor and ckeditor directives, I haven't found a solution that works for me. What I need is ...

Using Node.js to Update or Create a Google Document from a String with Drive API

I am currently working with the Drive API v3 (Node.js) to generate a new Google Doc containing some specific data. Additionally, I am interested in being able to "append" additional data to this existing Google Doc at a later time. Below is the code snipp ...

Is it possible to use both "npm install --global" and "--save" simultaneously?

I'm curious if it is practical to use both the --global and --save parameters in the npm install command simultaneously. For instance: npm install gulp -g -s From my understanding, since there is no package.json in the npm system folder, I assume th ...

Tips for developing effective client/server applications

For some time now, I have been attempting to develop multiplayer applications for a website. My initial project was to create a simple chat system, but the performance was quite sluggish. The process involved sending messages via AJAX to a PHP application ...

Extracting Information from Cloud Firestore through an Express API

I have encountered an issue while trying to retrieve data from four different documents in my firestore database collection. The current code successfully fetches data for the first function, but all subsequent functions return the same data as the first ...

Changing the req.path property within an expressjs middleware

I'm currently in the process of developing a middleware that will help eliminate locale strings from the path, such as /de/about becoming /about. This project is being implemented using express. To achieve this, I initially tried out the following mid ...

Monitoring the validity or errors in AngularJS input fields

I'm attempting to observe the $error or $valid status of a control. Here is the control in question: <form id="myForm" name="myForm"> <input name="myInput" ng-model="myInputMdl" business-validation/> </form> The business-validat ...

Enable express to disregard specific URL modifications

I'm currently working on creating a Single Page App using Express. One of the challenges I am facing is that the Express route feature forces the view to be re-rendered every time the URL changes and a GET request is sent to the server. My code typica ...

Verify the mining share in NodeJS prior to sending it to the pool (Stratum)

Struggling to verify if a share meets the minimum difficulty requirement. I have all the necessary data to generate a block hash and compare it with the difficulty level. However, my code is failing to produce a valid block hash, and I can't pinpoin ...

Adding personalized modules in Node Express

I'm a beginner in the world of Node.js and Express, and I am a bit confused about where to place certain files... I have some custom code that I want to use in my Express application - where should I store this code? Currently, it seems like I need t ...

Increase the number of rows in the table after applying the angular limitTo function

I have been attempting to increase the number of rows in a table by adjusting the limitTo value: <button ng-click="showMoreQueues()">Show More </button> The corresponding function is as follows: $increaseRows = function(){ $rowLimit += 2 ...

NodeJS QR code scanning with RaspberryPi camera

I'm working on a project to develop a nodeJS application that can scan QR codes using the Raspberry Pi3 board. I've been able to successfully implement this functionality with a USB camera using the Instascan node module. However, when attempting ...

The React App causing the File Explorer in Windows to completely freeze up

After using the npm command to create a React app, my laptop's fan suddenly became louder and I encountered issues with File Explorer. Opening folders became unresponsive and it kept loading files indefinitely. This has greatly impacted my work produc ...