NodeMailer : getaddrinfo Error - node.js

Looking for some insight into an error I'm getting.
on transporter.sendmail(func(err, info){}), the err variable returns this:
{ [Error: getaddrinfo ENOTFOUND smtp.gmail.com]
code: 'ENOTFOUND',
errno: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'smtp.gmail.com' }
I don't see any error documentation for nodemailer on their site or github, and I haven't found anything useful on Google searches. The closest I see is this SO post. I am trying to send about 50 emails once a week through a cron job.
I have tried this with and without the nodemailer-smtp-pool package, and my transporter currently looks like this:
var transporter = nodemailer.createTransport(smtpPool({
service: 'gmail',
auth: {
user: 'xxx#gmail.com',
pass: 'xxx'
},
maxConnections: 5,
maxMessages: 200
}));
I am not using XOATH yet, because I'm not under the impression that I need to. I have removed the DisplayUnlockCaptcha for the gmail account I'm using, but I don't think that's related. For what it's worth, I'm using the MEAN stack for this app.
It looks like 'smtp.gmail.com' is not being found when nodemailer makes the getaddrinfo call, but I can't understand why.
Any insight is appreciated
edit:
from the developer of nodemailer:
ENOTFOUND means that the app was not able to resolve DNS A record for
smtp.gmail.com. Probably something wrong with your DNS server. This is
handled by Node and not by Nodemailer, there's nothing Nodemailer can
do if a hostname is not resolved. If this happens randomly then you
could edit your application to try again in a moment.
and it doesn't look like nodemailer supports proxies, or ever plans to. looks like a dead end to me.

I had the same error with my nodemailer setup and I fixed it by changing the gmail password to not include any special characters.

var transporter = nodemailer.createTransport(smtpPool({
service: 'gmail',
secure: false, // true for 465, false for other ports
auth: {
user: 'xxx#gmail.com',
pass: 'xxx'
},
maxConnections: 5,
maxMessages: 200
}));
Try this, It should work fine.

Related

NodeMailer is blocked on Azure App Service

I have a NestJS app deployed to a Windows Azure App Service. Like everything else in Azure, it works fine on my machine until I deploy it. Getting a 500 error. It looks like some kind of port restriction.
Error message:
DEBUG Creating transport: nodemailer (6.7.2; +https://nodemailer.com/; SMTP/6.7.2[client:6.7.2])
DEBUG Sending mail using SMTP/6.7.2 DEBUG [DJemKiOruKY]
Resolved localhost as 127.0.0.1 [cache hit]
ERROR [DJemKiOruKY] connect EACCES 127.0.0.1:587
DEBUG [DJemKiOruKY] Closing connection to the server using 'destroy'
Here's the code that configures the mailer. Our noreply email has a custom domain (noreply#our_company.com)
const transporter = nodemailer.createTransport({
host: 'smtp.office365.com',
port: 587,
secure: false,
requireTLS: true,
auth: {
user: process.env.NOREPLY_EMAIL_ADDRESS,
pass: process.env.NOREPLY_EMAIL_PASSWORD
},
logger: true
});
const info = await transporter.sendMail({
from: `Sender Name <${process.env.NOREPLY_EMAIL_ADDRESS}>`,
to: process.env.NOREPLY_EMAIL_RECIPIENT,
...
You have to specifically allow outbound traffic on port 587.
How you do this depends on your setup.
To verify that the port is open, go to the app service console:
tcpping smtp.office365.com:587

Heroku Redis Add-On Error error:1408F10B:SSL routines:ssl3_get_record:wrong version number

After upgrading my Heroku Redis add-on to v6.2.3 from v4, Heroku papertrail logs display this error: Error accepting a client connection: error:1408F10B:SSL routines:ssl3_get_record:wrong version number I am connecting to Redis using NodeJs and the bull npm package (https://www.npmjs.com/package/bull). I found similar questions related to this error, along with Heroku documentation, and based on that I have set my bull redis options to the following:
redis: {
host: redisURL.hostname,
port: Number(redisURL.port),
password: redisURL.password,
tls: {
rejectUnauthorized: false,
},
},
Note the tls parameter. I have set it to Heroku's recommendations here: https://devcenter.heroku.com/articles/heroku-redis#connecting-in-node-js After getting stuck for a while, I attempted to simply comment out any client code that connects to Redis, delete the add-on, and re-provision the add-on. I expected to see no redis logs in papertrail when I did this, but I still see the same error, even when no code that connects to redis is being run... This leads me to believe maybe it's a setting on the actual Redis add-on instance, rather than an issue with my code, but I am at a loss.
Updates:
I logged into the redis:cli and did some investigation. client list reveals 2 client connections. 1 is the instance of the redis:cli I am running in my terminal, and another is the a client with a flag that means "the client is a replica node connection to this instance" (see https://redis.io/commands/client-list). What is interesting is the error that is being logged in papertrail shows the file descriptor for the client connection that is having the SSL error fd=12, while the 2 clients shown in client list have the file descriptors fd=10 and fd=11. So there must be another client connection with fd=12 that isn't appearing in client list command causing the error shown above.
Jasper Kennis' answer is correct. Adding tls: {rejectUnauthorized: false} fixed this issue for me. Unfortunately, Heroku only gives you a full REDIS_URL connection string, so you need to parse the password/host/port yourself (you can't specify both a URL and tls settings). Here's my BullModule.forRoot() config object if it helps:
redis: {
password: process.env.REDIS_URL.split('#')[0].split(':')[2],
host: process.env.REDIS_URL.split('#')[1].split(':')[0],
port: parseInt(process.env.REDIS_URL.split('#')[1].split(':')[1]),
tls: { rejectUnauthorized: false },
}
Using:
#nestjs/bull: 0.6.0,
Heroku redis: 6.2.3
Ran into the same problem. In addition to rejectUnauthorized: false, adding requestCert: true, solved it for me. In addition, some clients need agent: false, (but the version of Bull I'm using doesn't recognise that argument)
redis: {
host: redisURL.hostname,
port: Number(redisURL.port),
password: redisURL.password,
tls: {
rejectUnauthorized: false,
requestCert: true,
// agent: false, (not all clients accept this)
},
},

Cannot connect to AWS SES SMTP endpoint

I'm building an application that will use AWS SES to send email via SMTP. I've properly configured a domain and confirmed I can send email from that domain using the AWS SDK. I've created SMTP credentials and ensured the IAM user is properly configured with the right permissions. I've written a test script that uses Nodemailer to send the email.
The test script runs successfully using my personal development machine on my home network, but the script will NOT work when using the development laptop issued by my corporate client on my home network. The corporate laptop runs many security tools, including ZScaler. I also know that, due to the ZScaler service, NPM must be set to use a self-signed certificate (the command is npm config set cafile {CA_FILEPATH}).
I don't know why the script won't work on the corporate laptop, and I would appreciate some help in figuring what to try next.
Here's the script:
'use strict';
const nodemailer = require('nodemailer');
const runtest = async function() {
console.debug('Creating the SMTP transport');
const transporter = nodemailer.createTransport({
host: 'email-smtp.us-west-2.amazonaws.com',
port: 465,
secure: true,
auth: {
user: 'myusername',
pass: 'mypassword',
},
});
console.debug('Building mail options');
const mailOptions = {
from: 'me#example.com',
to: 'you#example.com',
subject: 'subject',
text: 'body',
html: '<h1>Hi</h1',
};
console.debug('Sending mail...');
const info = await transporter.sendMail(mailOptions);
console.debug(`Sent mail. Info: ${JSON.stringify(info, null, 2)}`);
console.info('Message sent!');
};
runtest().catch(console.error);
Here's the result when run from the corporate laptop:
Creating the SMTP transport
Building mail options
Sending mail...
Error: read ECONNRESET
at TLSWrap.onStreamRead (internal/stream_base_commons.js:200:27) {
errno: 'ECONNRESET',
code: 'ESOCKET',
syscall: 'read',
command: 'CONN'
}
Things I've tried:
Playing with TLS settings such as rejectUnauthorized: false and specifying the TLS version
Connecting to or disconnecting from the corporate VPN
I found a reference on this Github issue that suggested testing the connection with openssl. I ran this command openssl s_client -connect email-smtp.us-west-2.amazonaws.com:465, and this was the result (seems ok):
CONNECTED(0000021C)
write:errno=10054
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 336 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
In my case, it was the node version that caused this error. I have upgraded my node version to v12.x to fix the issue.

Unable to reach service using DNS

I am using the request package from NPM to handle some internal communication between services. I have also set the DNS server to the correct one (using Hashicorp Consul as my SD and DNS).
I can do a dig on my local machine (where the services are running) to the consul DNS server and I am able to get back the correct response (an IP and port number.
How I setup DNS in my app.js file6
dns.setServers([ `${config.consul.host}:8600` ]);
Set in a different file than app.js
options = {
baseUrl: `http://auth.service.consul`,
json: { '': '' },
headers: { authorization: '' }
};
Same file as options above
request.post(req.path, options, (error, response, body) => {
console.log(error);
if (error) throw error;
res.status(response.statusCode).json(body);
});
Error message:
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)
errno: 'ENOTFOUND',
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'auth.service.consul',
host: 'auth.service.consul',
port: 80 }
I am wanting to be able to make requests to the 'auth' service when using Consul as my DNS server. I currently have a very hacky way of doing this but really would like to use DNS.
I did find this but it is pertaining to the axios package not the request one I am trying to use even though it produces the same error the solution there didn't help.
Consul service discovery with DNS on Nodejs
You might have a chicken and egg problem. Try resolving ${config.consul.host} into an IP address and then call dns.setServers with that IP address.

How to catch email from local app server. Nodejs

I have lite nodejs server. I am trying to implement password reset flow. I use nodemailer to send email with reset password link. I want to test if I send email properly. I don't want to use any remote smpt.
What I can use on my local environment to catch emails and check if they are good?
Try this command:
python -m smtpd -n -c DebuggingServer localhost:1025
I used mailcatcher. It is a super simple SMTP server which catches any message sent to it to display in a web interface.
I have following configuration:
let smtpConfig = {
host: '127.0.0.1',
port: 1025,
secure: false, // upgrade later with STARTTLS
auth: {
user: 'user',
pass: 'password'
}
};
Do not forget to add user and password in auth section. It can be even white space. But it can't be empty string in this case you'll get error.
const smtpTransport = nodemailer.createTransport(smtpConfig);
And now you can see all sent emails here http://127.0.0.1:1080

Resources