如何修复此身份验证控制器,并使其在Node js(Express)中正常工作?

时间:2018-12-14 09:40:36

标签: node.js express mongoose nodemailer

我正在尝试通过节点邮寄程序发送验证电子邮件,并在用户注册时发送网格。我已经在用户创建功能中实现了所需的功能。在登录功能中还添加了一些部分,以检查是否验证了用户电子邮件,然后才让他们登录。但是,它在auth控制器中显示了一些语法错误,我无法弄清楚到底是什么错误? 这是代码:

身份验证控制器

module.exports = {
  async CreateUser(req, res) {
    const schema = Joi.object().keys({
      username: Joi.string()
        .min(4)
        .max(10)
        .required(),
      email: Joi.string()
        .email()
        .required(),
      password: Joi.string()
        .min(5)
        .required(),
    });

    const { error, value } = Joi.validate(req.body, schema);
    if (error && error.details) {
      return res.status(HttpStatus.BAD_REQUEST).json({ msg: error.details })
    }

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

    const userName = await User.findOne({
      username: Helpers.firstUpper(req.body.username)
    });
    if (userName) {
      return res
        .status(HttpStatus.CONFLICT)
        .json({ message: 'Username already exist' });
    }

    return bcrypt.hash(value.password, 10, (err, hash) => {
      if (err) {
        return res
          .status(HttpStatus.BAD_REQUEST)
          .json({ message: 'Error hashing password' });
      }

      const body = {
        username: Helpers.firstUpper(value.username),
        email: Helpers.lowerCase(value.email),
        password: hash,
      };
      User.create(body)
        .then(user => {
          const token = jwt.sign({ data: user }, dbConfig.secret, {
            expiresIn: '5h'
          });
          res.cookie('auth', token);
          res
            .status(HttpStatus.CREATED)
            .json({ message: 'User created successfully', user, token });
            var token = new Token({ _userId: user._id, token: crypto.randomBytes(16).toString('hex') });
            token.save(function (err) {
              if (err) { return res.status(500).send({ msg: err.message }); }
              var transporter = nodemailer.createTransport({
              service: 'Sendgrid',
              auth: { user: process.env.SENDGRID_USERNAME, pass: process.env.SENDGRID_PASSWORD } });
              var mailOptions = {
                 from: 'no-reply@yourwebapplication.com',
                  to: user.email, subject: 'Account Verification Token',
        text: 'Hello,\n\n' + 'Please verify your account by clicking the link: \nhttp:\/\/' + req.headers.host + '\/confirmation\/' + token.token +
              transporter.sendMail(mailOptions, function (err) {
                if (err) { return res.status(500).send({ msg: err.message }); }
                res.status(200).send('A verification email has been sent to ' + user.email + '.');
              })
            })
        })
        .catch(err => {
          res
            .status(HttpStatus.INTERNAL_SERVER_ERROR)
            .json({ message: 'Error occured' });
        });
    });
  },

  async LoginUser(req, res) {
    if (!req.body.username || !req.body.password) {
      return res
        .status(HttpStatus.INTERNAL_SERVER_ERROR)
        .json({ message: 'No empty fields allowed' });
    }

    await User.findOne({ username: Helpers.firstUpper(req.body.username) })
      .then(user => {
        if (!user) {
          return res
            .status(HttpStatus.NOT_FOUND)
            .json({ message: 'Username not found' });
        }

        return bcrypt.compare(req.body.password, user.password).then(result => {
          if (!result) {
            return res
              .status(HttpStatus.INTERNAL_SERVER_ERROR)
              .json({ message: 'Password is incorrect' });
          }
          if (!user.isVerified)
          return res
          .status(HttpStatus.INTERNAL_SERVER_ERROR)
          .json({ message: 'Email is not verified' });


          const token = jwt.sign({ data: user }, dbConfig.secret, {
            expiresIn: '5h'
          });
          res.cookie('auth', token);
          return res
            .status(HttpStatus.OK)
            .json({ message: 'Login successful', user, token });
        });
      })
      .catch(err => {
        return res
          .status(HttpStatus.INTERNAL_SERVER_ERROR)
          .json({ message: 'Error occured' });
      });
  }
};

VS在此行中显示第一个语法错误:

transporter.sendMail(mailOptions, function (err) {
                if (err) { return res.status(500).send({ msg: err.message }); }
                res.status(200).send('A verification email has been sent to ' + user.email + '.');
              })
            }) <====== under this ) I don't know what is wrong with it but it shows red line under that )
        })

我不认为)是此代码中的唯一错误。如果还有其他,该如何解决这个问题?

const userSchema = mongoose.Schema({
  username: { type: String },
  email: { type: String },
  isVerified: { type: Boolean, default: false },
  password: { type: String },

和令牌模型

const tokenSchema = new mongoose.Schema({
    _userId: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'User' },
    token: { type: String, required: true },
    createdAt: { type: Date, required: true, default: Date.now, expires: 43200 }
});
module.exports = mongoose.model('Token', tokenSchema);

该代码中应该修复哪些内容,以使auth函数按预期工作? 如果肉眼可见,如何解决上述)语法错误以及其他错误?

1 个答案:

答案 0 :(得分:1)

对于拼写错误,您只是忘了关闭mailOptions对象花括号。

此外,请确保始终仅向客户端发送响应,因此在完成所有回调后应将res.send()写入一次,并务必考虑错误处理。

这是User.creat函数的更新,您可以在其中看到重新发送位置已更改:

           User.create(body)
            .then(user => {
                const token = jwt.sign({ data: user }, dbConfig.secret, {
                    expiresIn: '5h'
                });
                res.cookie('auth', token);

                var token = new Token({ _userId: user._id, token: crypto.randomBytes(16).toString('hex') });
                token.save(function (err) {
                    if (err) { return res.status(500).send({ msg: err.message }); }
                    var transporter = nodemailer.createTransport({
                        service: 'Sendgrid',
                        auth: { user: process.env.SENDGRID_USERNAME, pass: process.env.SENDGRID_PASSWORD }
                    });
                    var mailOptions = {
                        from: 'no-reply@yourwebapplication.com',
                        to: user.email, subject: 'Account Verification Token',
                        text: 'Hello,\n\n' + 'Please verify your account by clicking the link: \nhttp:\/\/' + req.headers.host + '\/confirmation\/' + token.token
                    }

                    transporter.sendMail(mailOptions, function (err) {
                        if (err) { return res.status(500).send({ msg: err.message }); }
                        res.status(HttpStatus.CREATED).json({ message: 'User created successfully', user, token }); // or you can send another response as you like here
                    })          
                })
            })
            .catch(err => {
                res
                    .status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .json({ message: 'Error occured' });
            });