Эта функция является функцией регистрации, которая: 1) проверяет, существует ли электронная почта, введенная в форме, уже существует в базе данных 2) хэширует пароль, если электронная почта не существует 3) создает пользовательский экземпляр и сохраняет его в mongocollection 4) Отправляет верификационный токен в зарегистрированное электронное письмо для подтверждения учетной записи
. Я обнаружил ошибку в (3), когда .catch вызывается после попытки сохранить пользователя в базе данных, т.е. обещание не может быть решено. Я попытался выполнить обещание после const newUser = new User({...})
, и все до этого момента функционировало должным образом. Поэтому я сузился до ошибки: newUser
не может быть сохранено в коллекции. Я подозреваю, что я неправильно передаю параметры через каждую функцию внутри async.waterfall()
, но я надеюсь на любое понимание потенциальных проблем.
auth.js
const async = require("async");
const bcrypt = require("bcryptjs");
const nodemailer = require("nodemailer");
const User = require("..models/User").Model;
controller.register = (req, res) => {
// grab user data from registration form body
const { fname, lname, email, password } = req.body;
const validateEmail = (callback) => {
User.findOne({ "email.address": email})
.then(user => {
if(user) {
return res.status(403).json({
error: "This is email is already associated with a registered account"
});
} else {
callback(null, fname, lname, email, password);
};
})
.catch(err => {
return res.status(500).json({
errors: err.message || "The server experienced an error while validating this email"
});
});
};
// hash password from the form and pass form data to the database collection
const hashPassword = (fname, lname, email, password, callback) => {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash("", salt, (err, hash) => {
if(err) {
return res.status(500).json({
message: "The server was unable to hash your password",
errors: err
});
} else {
password = hash;
callback(null, fname, lname, email, hash);
};
});
});
};
const registerUser = (fname, lname, email, hash, callback) => {
// create user instance from form data and hashed password
const newUser = new User({
"name.first": fname,
"name.last": lname,
"email.address": email,
password: hash
});
// save user to database collection and pass user info to next function
newUser.save()
.then(user => {
callback(null, user);
})
.catch(err => {
return res.status(500).json({
success: false,
message: err.messsage || "An error occured while registering your new account"
});
});
};
const sendVerificationEmail = (user, callback) => {
// use nodemailer to send an verification token to the registered email address to verify the new account
};
// run series of functions above
async.waterfall([
validateEmail, // check whether registered email is already in database
hashPassword, // if not, hash the password
registerUser, // save the new user to the database collection
sendVerificationEmail // send verification token to email to verify the account
], (err, results) => {
if (err) {
return res.status(500).json({
message: "The server was unable to complete your request",
errors: err
});
} else {
return res.status(201).json(results);
}
});
}
Вот мойМодель для справки: User.js
const Schema = require("mongoose").Schema;
const model = require("mongoose").model;
const UserSchema = new Schema({
_id: Schema.Types.ObjectId,
name: {
first: {type: String, required: true},
last: {type: String, required: true}
},
email: {
address: {type: String, required: true, unique: true},
verified: {type: Boolean, default: false}
},
password: {type: String, required: true, minlength: 6},
});
module.exports = {
Schema: UserSchema,
Model: model("User", UserSchema)
}