Обычно я пытаюсь отправить пользователю URL-адрес для сброса его пароля. Я все правильно импортировал из mailer.js
и все работало нормально, пока не получил ответ. Он говорит
it can not read property response of undefined.
маршруты / пользователи. js
router.post("/reset-password/:email", emailController.createResetPasswordToken)
утилит / почтовой программы. js
const nodemailer = require("nodemailer")
let transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD
}
})
getPasswordResetURL = (user, token) => {
return `http://localhost:3000/reset-password/${user._id}/${token}`
}
const resetPasswordTemplate = (user, url) => {
const from = process.env.EMAIL
const to = user.email
const subject = "Password Reset"
const html = `
<p>Hey ${user.name || user.email},</p>
<p>We heard that you forgot your password. Sorry about that!</p>
<p>But don’t worry! You can use the following link to reset your password:</p>
<a href=${url}>${url}</a>
<p>If you don’t use this link within 1 hour, it will expire.</p>
`
}
module.exports = { transporter, getPasswordResetURL, resetPasswordTemplate }
emailController. js
const User = require("../models/User")
const bcrypt = require("bcrypt")
const jwt = require("jsonwebtoken")
const validator = require("validator")
const { transporter, getPasswordResetURL, resetPasswordTemplate } = require("../utils/mailer")
module.exports = {
createResetPasswordTokenAndSendMail: (req, res) => {
const email = req.params.email
User.findOne({ email }, (err, user) => {
if (err) console.log(err)
// res.json({user})
const hashedPassword = user.password
const createdAt = user.createdAt
const userId = user._id
// console.log(user.password, user.createdAt, userId )
const secret = hashedPassword + "-" + createdAt
const token = jwt.sign({ userId }, secret, {
expiresIn: 3600
})
// console.log(token)
// console.log(user)
const url = getPasswordResetURL(user, token)
// console.log(url)
const emailTemplate = resetPasswordTemplate(user, url)
// console.log(emailTemplate, "l26")
const sendEmail = () => {
transporter.sendMail(emailTemplate, (err, info) => {
if (err) console.log(err)
// console.log(info, "L31")
console.log("email sent successfully", info.response)
})
}
sendEmail()
})
}
}
Когда я тестировал этот API в Почтальоне, я получил эту ошибку в консоли:
{ Error: Missing credentials for "PLAIN"
at SMTPConnection._formatError (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:784:19)
at SMTPConnection.login (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:448:38)
at connection.connect (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-transport/index.js:271:32)
at SMTPConnection.once (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:215:17)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:106:13)
at SMTPConnection.emit (events.js:208:7)
at SMTPConnection._actionEHLO (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:1313:14)
at SMTPConnection._processResponse (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:942:20)
at SMTPConnection._onData (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:749:14)
at TLSSocket.SMTPConnection._onSocketData.chunk (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at TLSSocket.Readable.push (_stream_readable.js:208:10) code: 'EAUTH', command: 'API' }
/home/voidrealm/Desktop/myApp/controllers/emailController.js:32
console.log("email sent successfully", info.response)
^
TypeError: Cannot read property 'response' of undefined
at transporter.sendMail (/home/voidrealm/Desktop/myApp/controllers/emailController.js:32:69)
at transporter.send.args (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/mailer/index.js:226:21)
at connection.login.err (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-transport/index.js:282:36)
at SMTPConnection.login (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:448:24)
at connection.connect (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-transport/index.js:271:32)
at SMTPConnection.once (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:215:17)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:106:13)
at SMTPConnection.emit (events.js:208:7)
at SMTPConnection._actionEHLO (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:1313:14)
at SMTPConnection._processResponse (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:942:20)
at SMTPConnection._onData (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:749:14)
at TLSSocket.SMTPConnection._onSocketData.chunk (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
Обновление
После настройки OAuth я получаю ту же ошибку :
Вот мой обновленный код.
mailer. js
const nodemailer = require("nodemailer")
let transporter = nodemailer.createTransport({
service: "gmail",
auth: {
type: "OAuth2",
user: process.env.EMAIL,
clientId: process.env.clientId,
clientSecret: process.env.clientSecret,
refreshToken: process.env.refreshToken,
accessToken: process.env.accessToken,
expiresIn: process.env.expiresIn
}
})
getPasswordResetURL = (user, token) => {
return `http://localhost:3000/reset-password/${user._id}/${token}`
}
const resetPasswordTemplate = (user, url) => {
from = process.env.EMAIL,
to = user.email,
subject = "Password Reset",
auth = {
user: user.email,
refreshToken: process.env.refreshToken,
accessToken: process.env.accessToken,
expiresIn: process.env.expiresIn
},
html = `
<p>We heard that you forgot your password. Sorry about that!</p>
<p>But don’t worry! You can use the following link to reset your password:</p>
<a href=${url}>${url}</a>
<p>If you don’t use this link within 1 hour, it will expire.</p>
`
return {from, to, subject, html, auth}
}
module.exports = { transporter, getPasswordResetURL, resetPasswordTemplate }
emailController. js
const User = require("../models/User")
const bcrypt = require("bcrypt")
const jwt = require("jsonwebtoken")
const validator = require("validator")
const { transporter, getPasswordResetURL, resetPasswordTemplate } = require("../utils/mailer")
module.exports = {
createResetPasswordTokenAndSendMail: (req, res) => {
const email = req.params.email
User.findOne({ email }, (err, user) => {
if (err) console.log(err)
// res.json({user})
const hashedPassword = user.password
const createdAt = user.createdAt
const userId = user._id
// console.log(user.password, user.createdAt, userId )
const secret = hashedPassword + "-" + createdAt
const token = jwt.sign({ userId }, secret, {
expiresIn: 3600
})
// console.log(token)
// console.log(user)
const url = getPasswordResetURL(user, token)
// console.log(url)
const emailTemplate = resetPasswordTemplate(user, url)
console.log(emailTemplate, "l26")
const sendEmail = () => {
transporter.sendMail(emailTemplate, (err, info) => {
if (err) console.log(err)
// console.log(info, "L31")
console.log("email sent successfully", info.response)
})
}
sendEmail()
})
}
}
Консоль
{ Error: invalid_request
at postRequest (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:259:33)
at PassThrough.req.once (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:328:20)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at PassThrough.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9) code: 'EAUTH', command: 'AUTH XOAUTH2' }
/home/voidrealm/Desktop/myApp/controllers/emailController.js:33
console.log("email sent successfully", info.response)
^
TypeError: Cannot read property 'response' of undefined
at transporter.sendMail (/home/voidrealm/Desktop/myApp/controllers/emailController.js:33:69)
at transporter.send.args (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/mailer/index.js:226:21)
at connection.login.err (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-transport/index.js:282:36)
at _auth.oauth2.getToken (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:1709:24)
at generateCallback (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:111:13)
at postRequest (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:259:24)
at PassThrough.req.once (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:328:20)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at PassThrough.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
Примечание : я получаю все значения учетных данных, необходимые для аутентификации, и сохранил их в моем файле .env .