0

When I click reset password button it throws user is not defined in the command prompt for back-end. I am using Mongoose with Node.js Express. Here is the code for both model and controller.

controller

const User = require('../models/userModels');
const passwordResetToken = require('../models/resettokenModels');

async ResetPassword(req, res) {
    if (!req.body.email) {
      return res
        .status(HttpStatus.INTERNAL_SERVER_ERROR)
        .json({ message: 'Email is required' });
    }

    const userEmail = await User.findOne({
      email: Helpers.lowerCase(req.body.email)
    });
    if (!userEmail) {
      return res
        .status(HttpStatus.CONFLICT)
        .json({ message: 'Email does not exist' });
    }

            var resettoken = new passwordResetToken({ _userId: user._id, resettoken: crypto.randomBytes(16).toString('hex') });
            resettoken.save(function (err) {
                if (err) { return res.status(500).send({ msg: err.message }); }
                var transporter = nodemailer.createTransport({
                    service: '"SendGrid"',
                    auth:
                     {
                      user: 'email',
                      pass: 'password'
                     }
                });
                var mailOptions = {
                    from: 'email',
                    subject: 'Node.js Password Reset',
                    text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
                      'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
                      'http://' + req.headers.host + '/reset/' + resettoken + '\n\n' +
                      'If you did not request this, please ignore this email and your password will remain unchanged.\n'
                }

                transporter.sendMail(mailOptions 
                )          
            })

        .catch(err => {
            res
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .json({ message: 'Error occured' });
        });
    },

And here is the model

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const resettokenSchema = new mongoose.Schema({
    _userId: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'User' },
    resettoken: { type: String, required: true },
    createdAt: { type: Date, required: true, default: Date.now, expires: 43200 },
});

module.exports = mongoose.model('passwordResetToken', resettokenSchema);

USer model

const userSchema = new mongoose.Schema({
  username: { type: String },
  email: { type: String },
  password: { type: String },
  ...
 ...

Error is showing in this line inside controller

 var resettoken = new passwordResetToken({ _userId: user._id, resettoken: crypto.randomBytes(16).toString('hex') });

What can cause such an issue?

4
  • I don't see a user object, I see a userEmail object though... Commented Jan 30, 2019 at 9:41
  • I can import User model as well if it's needed here. In the project it exists in both controller imports and as a model. Commented Jan 30, 2019 at 9:44
  • think you're missing the hint here, you need to rename user._id to userEmail._id Commented Jan 30, 2019 at 9:46
  • Not it throws can't read property of catch in this line: .catch(err => { res .status(HttpStatus.INTERNAL_SERVER_ERROR) .json({ message: 'Error occured' }); it's the last block of controller, Commented Jan 30, 2019 at 9:51

1 Answer 1

1

As mentioned in comments you are not setting user to anything.

edit:

This is using your user schema, you have shown above that the user schema has username, email, password, ect.

const user = await User.findOne({
      email: Helpers.lowerCase(req.body.email)
    });

Your reset token needs to do this:

var resettoken = new passwordResetToken({ _userId: user._id, resettoken: crypto.randomBytes(16).toString('hex') });

Your nodemailer needs to do this:

var mailOptions = {
  from: '[email protected]',
  to: user.email,
  subject: 'Node.js Password Reset',
  text: 'some message'
}

transporter.sendMail(mailOptions)  

Sign up to request clarification or add additional context in comments.

8 Comments

It doesn't solve the problem. After that I removed last catch block even after that it throws another error.
I've added this line in email options too. to: userEmail, It throws can't send mail all recipients are rejected.
what is userEmail. Looking at your code that's not the email, thats the user object. Perhaps consider renaming your variable userEmail to user. Because I think you're trying to do user.email - based on your schema.
in user schema it's just email.
i've edited my response to better answer and outline what I think is wrong with your current implementation. To be clear, in your code sample above, the user schema is not just email.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.