असल में, मैं उपयोगकर्ता को अपना पासवर्ड रीसेट करने के लिए एक यूआरएल भेजने की कोशिश कर रहा हूं। मैंने mailer.js से सब कुछ सही ढंग से आयात किया है और जब तक मुझे प्रतिक्रिया नहीं मिली तब तक सब कुछ ठीक रहा। यह कह रहा है

it can not read property response of undefined.


मार्ग/users.js

router.post("/reset-password/:email", emailController.createResetPasswordToken)

utils/mailer.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 }

ईमेलकंट्रोलर.जेएस

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: 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 }

ईमेलकंट्रोलर.जेएस

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 फ़ाइल में सहेजा गया है।

0
metalHeadDev 22 फरवरी 2020, 13:23
आपको पहले Missing credentials for "PLAIN" त्रुटि वापस मिलती है, इसका मतलब if (err) console.log(err) निष्पादित किया गया है, फिर info शून्य हो जाएगा।
 – 
hoangdv
22 फरवरी 2020, 17:27

2 जवाब

इस उत्तर के अनुसार, Gmail/Google ऐप ईमेल सेवा को प्रमाणीकरण के लिए OAuth2 की आवश्यकता होती है। सादा पाठ पासवर्ड को Google खाते पर सुरक्षा सुविधाओं को मैन्युअल रूप से अक्षम करने की आवश्यकता होगी।

इसलिए सुनिश्चित करें कि आप या तो अपने खाते से सुरक्षा सुविधाओं को अक्षम कर दें या oAuth2 का उपयोग करें।

साथ ही, मुझे यकीन नहीं है कि आप Nodemail के किस संस्करण का उपयोग कर रहे हैं, लेकिन जानकारी तर्क में response प्रोप शामिल नहीं है। इसमें एक envelope और एक messageId संपत्ति है।

0
Nick Rameau 22 फरवरी 2020, 13:38
हां, मैंने gmail की कम सुरक्षित ऐप्स सुविधा चालू कर दी है। साथ ही ऐसा लगता है कि info परिभाषित किया गया है।
 – 
metalHeadDev
22 फरवरी 2020, 13:47
1
अपने कोड को यहां प्रारूपित करने का प्रयास करें: nodemailer.com/smtp/#1-single-connection
 – 
Nick Rameau
22 फरवरी 2020, 13:52
मेरी मशीन पर Nodemailer का संस्करण 6.4.2 चल रहा है। क्या यह OAuth2 का समर्थन करता है?
 – 
metalHeadDev
22 फरवरी 2020, 14:00
1
हाँ, मुझे विश्वास है कि यह करता है।
 – 
Nick Rameau
22 फरवरी 2020, 14:03
1
निर्भर करता है, आप उनके बारे में यहां अधिक जान सकते हैं: nodemailer.com/smtp/oauth2/#oauth- 3लो. 3LO अधिक विस्तृत है।
 – 
Nick Rameau
22 फरवरी 2020, 14:17

आपने कहीं भी ट्रांसपोर्टर घोषित नहीं किया है।

इसे नीचे दिए गए कोड को निष्पादित करने का प्रयास करें,

var transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: process.env.EMAIL,
    pass: process.env.PASSWORD
  }
});

var mailOptions = {
  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>
    `
};

transporter.sendMail(mailOptions, function(error, info){
  if (error) {
    console.log(error);
  } else {
    console.log('Email sent: ' + info.response);
  }
});

संपादित
अपना एचटीएमएल प्रारूप बदलें जैसा कि मैं उपरोक्त कोड में करता हूं।

0
Pushprajsinh Chudasama 11 मार्च 2020, 07:10
मैंने transporter ऊपर घोषित कर दिया है।
 – 
metalHeadDev
22 फरवरी 2020, 17:19
मुझे आपका जवाब नहीं मिला। यह वही त्रुटि फेंक रहा है। साथ ही, मैं यहां sendMail फ़ंक्शन को परिभाषित नहीं कर रहा हूं।
 – 
metalHeadDev
22 फरवरी 2020, 18:22
मैंने अपना कोड संपादित कर लिया है। इस पर एक नज़र डालो। @metalHeadDev
 – 
Pushprajsinh Chudasama
11 मार्च 2020, 07:11