1

I try posting the token gotten from my registration via the code below, but I get the error, maximum call stack exceeded

exports.activationController = (req, res) => {
  const { token } = req.body;

  exports.activationController = (req, res) => {
  const { token } = req.body;

  if (token) {
    jwt.verify(token, process.env.JWT_ACCOUNT_ACTIVATION, (err, decoded) => {
      if (err) {
        return res.status(401).json({
          errors: 'Expired link. Signup again'
        });
      } else {
        const { name, email, password } = jwt.decode(token);

        const user = new User({
          name,
          email,
          password
        });

        user.save((err, user) => {
          if (err) {
            return res.status(401).json({
              errors: 'User cannot be saved.'
            });
          } else {
            return res.json({
              success: true,
              message: 'Signup success'
            });
          }
        });
      } 
    });
  } else {
    return res.json({
      message: 'Please try again.'
    });
  }
};

I have done the registration like this

exports.registerController = (req, res) => {
    const { name, email, password } = req.body;
    const errors = validationResult(req);
    

    if (!errors.isEmpty()) {
      const firstError = errors.array().map(error => error.msg)[0];
      return res.status(422).json({
        errors: firstError
      });
    } else {
      User.findOne({
        email
      }).exec((err, user) => {
        if (user) {
          return res.status(400).json({
            errors: 'Email is taken'
          });
        }
      });

      const token = jwt.sign(
        {
          name,
          email,
          password
        },
        process.env.JWT_ACCOUNT_ACTIVATION,
        {
          expiresIn: '5m'
        }
      );

      const emailData = {
        from: process.env.EMAIL_FROM,
        to: email,
        subject: 'Account activation link',
        html: `
                  <h1>Please use the following to activate your account</h1>
                  <button style="padding: 15px; background-color: blue; text-align:center; opacity: 0.2; outline: none; border-radius: 10px;"><a style="text-decoration: none; color: white;" href="${process.env.CLIENT_URL}/users/activate/${token}">Activate your account</a></button>
                  <hr />
                  <p>This email may containe sensetive information</p>
                  <p>${process.env.CLIENT_URL}</p>
              `
      };

I get the error "maximum call stack exceeded" when posting the activation" by using postman. I really do not know where in my code, this error is coming from

This is the response

RangeError: Maximum call stack size exceeded
   at RegExp.test (<anonymous>)
   at _pathToPositionalSyntax (C:\Users\User\Documents\My projects\greenlifeapp\node_modules\mongoose\lib\schema.js:854:16)
   at Schema.pathType (C:\Users\User\Documents\My projects\greenlifeapp\node_modules\mongoose\lib\schema.js:1200:21)
   at model.$set (C:\Users\User\Documents\My projects\greenlifeapp\node_modules\mongoose\lib\document.js:1160:33)
   at model.set [as password] (C:\Users\User\Documents\My projects\greenlifeapp\node_modules\mongoose\lib\helpers\document\compile.js:174:19)
   at model.<anonymous> (C:\Users\User\Documents\My projects\greenlifeapp\models\auth.model.js:34:19)
   at VirtualType.applySetters (C:\Users\User\Documents\My projects\greenlifeapp\node_modules\mongoose\lib\virtualtype.js:167:16)
   at model.$set (C:\Users\User\Documents\My projects\greenlifeapp\node_modules\mongoose\lib\document.js:1264:12)
   at model.set [as password] (C:\Users\User\Documents\My projects\greenlifeapp\node_modules\mongoose\lib\helpers\document\compile.js:174:19)
   at model.<anonymous> (C:\Users\User\Documents\My projects\greenlifeapp\models\auth.model.js:34:19)

The mongoose model where I have defined the user

const mongoose = require('mongoose')

const userSchema = new mongoose.Schema({
    name: {
        type: String,
        trim: true,
        required: true,
        unique: true,
        lowercase: true
    }, 
    name: {
        type: String,
        trim: true,
        required: true     
    }, 
    hashed_password: {
        type: String,
        required: true
    },
    salt: String,
    role: {
        type: String,
        default: 'Normal'
    },
    resetPasswordLink: {
        data: String,
        default: ''
    }
}, {timeStamp: true})

// Virtual password
userSchema.virtual('password')
.set(function(password){
    this.password = password
    this.salt = this.makeSalt()
    this.hashed_password = this.encryptPassword(password)
})
.get(function(){
    return this._password
})

// Methods
userSchema.methods = {
    // Generate salt
    makeSalt: function(){
        return Math.round(new Date().valueOf() * Math.random()) + ''
    },
    // Encrypt Password
    encryptPassword: function(password){
        if(!password) return ''
        try{
            return crypto
            .createHmac('sha1', this.salt)
            .update(password)
            .digest('hex')
        } catch (err) {
            return ''
        }
    },
    authenticate: function (plainPassword) {
        return this.encryptPassword(plainPassword) === this.hashed_password
    }
}

module.exports = mongoose.model('User', userSchema)
3
  • Provide error stack trace to help others to figure out where the error occurs. Currently it's near to impossible to tell what's going on. Commented Nov 16, 2021 at 10:34
  • Happens when your recursive functions take too long to run, use an iterative approach. Commented Nov 16, 2021 at 10:45
  • Can you also share the mongoose model where User is defined? The stack trace points to a problematic (recursive?) regular expression, perhaps for validating the email? Commented Nov 16, 2021 at 16:28

1 Answer 1

0

All operations related to database like find,save,findOne are asynchronous in nature. To execute that you should either use promise or async/await. For ex. to save the user you should use this

exports.activationController = async (req, res) => {
  const { token } = req.body;

  if (token) {
    jwt.verify(token, process.env.JWT_ACCOUNT_ACTIVATION, (err, decoded) => {
      if (err) {
        return res.status(401).json({
          errors: 'Expired link. Signup again'
        });
      } else {
        const { name, email, password } = jwt.decode(token);

        const user = new User({
          name,
          email,
          password
        });

        await user.save((err, user) => {
          if (err) {
            return res.status(401).json({
              errors: 'User cannot be saved.'
            });
          } else {
            return res.json({
              success: true,
              message: 'Signup success'
            });
          }
        });
      } 
    });
  } else {
    return res.json({
      message: 'Please try again.'
    });
  }
};

and for registration like this

exports.registerController = async (req, res) => {
    const { name, email, password } = req.body;
   // if validationResult is async function use await here as well
    const errors = validationResult(req);
    

    if (!errors.isEmpty()) {
      const firstError = errors.array().map(error => error.msg)[0];
      return res.status(422).json({
        errors: firstError
      });
    } else {
      await User.findOne({
        email
      }).exec((err, user) => {
        if (user) {
          return res.status(400).json({
            errors: 'Email is taken'
          });
        }
      });

      const token = jwt.sign(
        {
          name,
          email,
          password
        },
        process.env.JWT_ACCOUNT_ACTIVATION,
        {
          expiresIn: '5m'
        }
      );

      const emailData = {
        from: process.env.EMAIL_FROM,
        to: email,
        subject: 'Account activation link',
        html: `
                  <h1>Please use the following to activate your account</h1>
                  <button style="padding: 15px; background-color: blue; text-align:center; opacity: 0.2; outline: none; border-radius: 10px;"><a style="text-decoration: none; color: white;" href="${process.env.CLIENT_URL}/users/activate/${token}">Activate your account</a></button>
                  <hr />
                  <p>This email may containe sensetive information</p>
                  <p>${process.env.CLIENT_URL}</p>
              `
      };

Let me know if it helps or not.

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

2 Comments

It didn't :( I tried the possible, but it still didnt work
Can you share your code repo. I need to know the filenames to decode the error.

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.