Я пытаюсь отправить подтверждение по электронной почте, когда пользователь зарегистрируется.Интересен тот факт, что когда я нажимаю кнопку регистрации, она работает, создает пользователя и переходит на страницу, на которой он должен перемещаться.Но он не отправляет подтверждение по электронной почте и в командной строке показывает следующую ошибку: Невозможно установить заголовки после их отправки клиенту
Вот код:
Контроллер аутентификации
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 age = moment().diff(moment([value.byear, value.bmonth - 1, value.bday]), 'years');
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 emailtoken = new emailToken({ _userId: user._id, emailtoken: crypto.randomBytes(16).toString('hex') });
emailtoken.save(function (err) {
if (err) { return res.status(500).send({ msg: err.message }); }
var transporter = nodemailer.createTransport({
service: 'Sendgrid',
auth: { api_key:'api key is here' }
});
var mailOptions = {
from: 'email@email.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\/' + emailtoken.emailtoken
}
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, emailtoken }); // or you can send another response as you like here
})
})
})
.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' });
});
}
};
модель пользователя:
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' },
emailtoken: { type: String, required: true },
createdAt: { type: Date, required: true, default: Date.now, expires: 43200 }
});
module.exports = mongoose.model('emailToken', tokenSchema);
В соответствии с командной строкой, где-то здесь, в контроллере аутентификации, должно быть что-то не так:
var transporter = nodemailer.createTransport({
service: 'Sendgrid',
auth: { api_key:'api key is here' }
});
var mailOptions = {
from: 'email@email.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\/' + emailtoken.emailtoken
}
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, emailtoken }); // or you can send another response as you like here
})
})
})
Также во внешнем интерфейсе я использую Angular.Что случилось?Почему он не отправляет электронное письмо и выдает эту странную ошибку?