skip to Main Content

I created a user authentication system where user needs to verify first with otp after then user can login but the problem is while updating user verified status password is also updating automatically. I can’t figure out the problem why is this happening. I sharing my code anyone help me with this

Here is my verify and login controller

`

const verifyUser = expressAsyncHandler(async (req, res) => {
  let minutes = 10;
  let now = new Date().getTime();
  let otpTime;
  let otpFromDatabase;
  const { otp } = req.body;
  const user = await User.findById(req.user._id);
  if (!user) {
   res.status(404);
   throw new Error("User not found");
  }
 otpTime = new Date(user.otpTime).getTime();
 otpFromDatabase = user.otp;
 console.log("Time-Diff", now - otpTime > minutes * 60 * 1000);
 console.log("Time-Diff 2", now - otpTime);
 if (now - otpTime > minutes * 60 * 1000) {
  user.isOtpExpired = true;
  const otpExpiredUpdateUser = await user.save();
  res.json({
   otpTime: otpExpiredUpdateUser.otpTime,
   otpFromDatabase: otpExpiredUpdateUser.otp,
   otpExpired:otpExpiredUpdateUser.isOtpExpired,
  });
 } else {
   if (otpFromDatabase !== otp) {
    res.status(400);
    throw new Error("Please enter a valid OTP");
   } else {
    user.isVerified = true;
    const verifiedUser = await user.save();
    res.json({
    _id: verifiedUser._id,
    name: verifiedUser.name,
    email: verifiedUser.email,
    token: generateToken(verifiedUser._id),
   });
  }
}});

const loginUser = expressAsyncHandler(async (req, res) => {
 const { email, password } = req.body;
 let verifiedUser;
 let matchUserPassword;
 const user = await User.findOne({ email });
 if (user) {
  verifiedUser = user.isVerified;
  matchUserPassword = await user.matchPassword(password);
  console.log(verifiedUser);
  console.log(matchUserPassword);
 }
 if (user && (await user.matchPassword(password))) {
  if (verifiedUser) {
   res.json({
    _id: user._id,
    name: user.name,
    email: user.email,
    token: generateToken(user._id),
   });
  } else {
    res.status(400);
    throw new Error("Please verify the email!");
  }
 } else {
  res.status(401);
  throw new Error("Invalid email or password");
 }});

I am also sharing the my schema

const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");

const userSchema = mongoose.Schema(
    {
        name: {
            type: String,
            required: true,
        },
        email: {
            type: String,
            unique: true,
            required: true,
        },
        password: {
            type: String,
            required: true,
        },
        mobile_number: {
            type: Number,
            required: true,
        },
        otp: {
            type: Number,
            required: true,
        },
        isOtpExpired: {
            type: Boolean,
            default: false,
            required: true,
        },
        otpTime: {
            type: Date,
            default: new Date().getTime().toString(),
        },
        isVerified: {
            type: Boolean,
            default: false,
        },
        isAdmin: {
            type: Boolean,
            default: false,
            required: true,
        },
    },
    {
        timestamps: {
            createdAt: "created_at",
            updatedAt: "modified_at",
        },
    }
);

userSchema.methods.matchPassword =
    async function (enteredPassword) {
        return await bcrypt.compare(
            enteredPassword,
            this.password
        );
    };

userSchema.pre("save", async function (next) {
    if (!this.isModified) {
        next();
    }

    const salt = await bcrypt.genSalt(10);
    this.password = await bcrypt.hash(
        this.password,
        salt
    );
});

const User = mongoose.model("User", userSchema);

module.exports = User;

I want only the fields should be updated that I mentioned in my code not other just like password

2

Answers


  1. If you want to update only specific fields in your code, I think you can use Mongoose’s select method when querying the user from the database like this:

    const user = await User.findById(req.user._id).select('isVerified otpTime otp isOtpExpired');
    

    This will ensure that only the fields isVerified, otpTime, otp, and isOtpExpired are returned from the database, and any other fields in the User schema will be ignored.

    Similarly, when saving the user after updating isVerified, try use the select method to update only the isVerified field, like this:

    user.isVerified = true;
    const verifiedUser = await user.save({ select: 'isVerified' });
    

    This will update only the isVerified field in the database and ignore any other changes made to the User schema.

    Hope this helps!

    Login or Signup to reply.
  2. To update only specific fields in Mongoose, you can use the updateOne method with the $set operator. Here’s an example:

    const user = await User.findById(req.user._id);
    if (!user) {
      res.status(404);
      throw new Error("User not found");
    }
    
    // only update the isVerified field
    const update = {
      $set: {
        isVerified: true
      }
    };
    
    const options = {
      new: true // return the updated document
    };
    
    const updatedUser = await User.updateOne({_id: user._id}, update, options);
    res.json({
      _id: updatedUser._id,
      name: updatedUser.name,
      email: updatedUser.email,
      // include other fields you want to return
    });
    

    In this example, we only update the isVerified field of the user document. We create an update object that includes only the field we want to update, using the $set operator. We then use the updateOne method to update the document, passing in the _id of the user we want to update, the update object, and some options. The new option tells Mongoose to return the updated document. Finally, we return the updated fields in the response.

    You can modify this example to update any other fields you need to update. Just make sure to use the $set operator to only update the specific fields you need.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search