Nodemailer - SMTP Timeout - office365 - javascript

I am trying to use SMTP connection with nodemailer with office365 mail.
When I try to send mail, it throws up this error -
Error: connect ETIMEDOUT xx.xxx.xxx.xxx:587
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1161:14)
errno: 'ETIMEDOUT',
code: 'ECONNECTION',
syscall: 'connect',
address: 'xx.xxx.xxx.xxx',
port: 587
It is not a proxy issue, since I tried outside of the network and it throws up the same error as well.
`
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
host: 'smtp.office365.com',
secure: false,
auth: {
user: "xxxxx#xxx.com",
pass: "xxxxx"
},
tls: {
ciphers: 'SSLv3'
}
});
var message = {
from: 'Sender Name <xxx#xxx.com>',
to: '"Receiver Name" <xxx#xxx.com>',
subject: 'Nodemailer',
text: 'Hello to myself!'
};
transporter.sendMail(message, function(error, response) {
if (error) {
console.log('Error occured');
res.end("<html><body><h1>error</h1></body></html>");
console.log(error);
return;
} else {
console.log(response);
res.end("<html><body><h1>success</h1></body></html>");
console.log('Message sent successfully!');
}
});
`
I tried with other services as well like Gmail, it also gives the same error inside and outside the network.

Do you have a local firewall or anti-virus product that does port blocking? My company routinely blocks computers from making outbound connections on common SMTP ports because it was a common multi-mailer virus propagation path. smtp.office365.com responds on both port 25 and 587 from a host I know to be able to initiate outbound SMTP traffic.
[~]# nmap -p25,587 smtp.office365.com
Starting Nmap 7.60 ( https://nmap.org ) at 2018-12-04 10:39 EST
Nmap scan report for smtp.office365.com (40.97.170.178)
Host is up (0.027s latency).
PORT STATE SERVICE
25/tcp open smtp
587/tcp open submission

this might be a bit late but this is more for anyone else in the future.
Common cause for timeouts is you have to enable SMTP, if using a mac this can be done through PowerShell then look to here. If youre on a mac, you'll have to install WSman because it doesnt come with powershell. run on port 587. set secure to false. then make sure your config email and the email in your auth and data for postman are the same.

Related

I am trying to connect my web page to my local server database but I am getting error ECONNREFUSED [duplicate]

This question already has answers here:
MySQL ERROR 1045 (28000): Access denied for user 'bill'#'localhost' (using password: YES)
(43 answers)
Closed last year.
errno: -61,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3000,
fatal: true
I am using Mac OS and VS Code to connect to my local server. I have connected mysql workbench to VSCode as well and it is working fine. But when I try to connect it with my program it is not working. I changed the hostname from 'localhost' to '127.0.0.1' as well still no luck. Also, I changed my port from 3306 to 3000 as it was not connecting and I got the following error
code: 'ER_ACCESS_DENIED_ERROR',
errno: 1045,
sqlMessage: "Access denied for user 'usersql'#'localhost' (using password: YES)",
sqlState: '28000',
fatal: true
My code:
const { createPool } = require('mysql')
const pool = createPool({
host: "127.0.0.1",
user: "usersql",
password: "password!23",
database: "userdb",
connectionLimit: 10,
port: 3000
})
pool.query(`select * from userdb.New_Customer`, function(err, result, fields) {
if (err) {
return console.log(err);
}
return console.log(result);
})
It's a login failure. The reason can be anything from active firewall, to wrong authentication mode to wrong user credentials.
this might help you, MySQL ERROR 1045 (28000): Access denied for user 'bill'#'localhost' (using password: YES)

Using ssl with node mysql and Cleardb

I have a free ClearDB account that I got through Heroku (as a resource)
It gives me the
CA certificate
Client cert
Client Key
These are all in .pem format
const fs = require('fs');
const ssl = {
ca: fs.readFileSync('cleardb-ca.pem', "utf-8"),
key: fs.readFileSync('cleardb-key.pem', "utf-8"),
cert: fs.readFileSync('cleardb-cert.pem', "utf-8")
};
const cleardb = mysql.createConnection({
host:"HOST",
user: "USER",
password: "PWD",
database: "DB",
ssl: ssl
});
cleardb.connect((err) => {
if (err) throw err;
console.log('connected!');
});
This keeps throwing
Error: 22928:error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol:c:\ws\deps\openssl\openssl\ssl\statem\statem_lib.c:1929:
and then the error stacktrace shows an Object like
library: 'SSL routines', function: 'ssl_choose_client_version', reason: 'unsupported protocol', code: 'HANDSHAKE_SSL_ERROR', fatal: true
The SSL routines:ssl_choose_client_version:unsupported error is the same exact error I get when I try connecting to this DB through the MySQL CLI.
I.e. mysql --host=HOST --ssl-capath=. --ssl-cert=cleardb-cert.pem --ssl-key=cleardb-key.pem --user=USER
I'm able to connect through both Node and the CLI if I do not use SSL.
Any idea what's going on here?
Should I really worry that much about using SSL? I've read that if the option for transport security exists, that you should elect to use it.

Missing credentials for "PLAIN" nodemailer

I'm trying to use nodemailer in my contact form to receive feedback and send them directly to an email. This is the form below.
<form method="post" action="/contact">
<label for="name">Name:</label>
<input type="text" name="name" placeholder="Enter Your Name" required><br>
<label for="email">Email:</label>
<input type="email" name="email" placeholder="Enter Your Email" required><br>
<label for="feedback">Feedback:</label>
<textarea name="feedback" placeholder="Enter Feedback Here"></textarea><br>
<input type="submit" name="sumbit" value="Submit">
</form>
This is what the request in the server side looks like
app.post('/contact',(req,res)=>{
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'user#gmail.com',
password: 'password'
}
});
var mailOptions = {
from: req.body.name + '<' + req.body.email + '>',
to: 'bantspl#gmail.com',
subject: 'Plbants Feedback',
text: req.body.feedback
};
transporter.sendMail(mailOptions,(err,res)=>{
if(err){
console.log(err);
}
else {
}
});
I'm getting the error Missing credentials for "PLAIN". Any help is appreciated, thank you very much.
You have
auth: {
user: 'user#gmail.com',
password: 'password'
}
But you should write this
auth: {
user: 'user#gmail.com',
pass: 'password'
}
Just rename password to pass.
I was able to solve this problem by using number 3, Set up 3LO authentication, example from the nodemailer documentation (link: https://nodemailer.com/smtp/oauth2/). My code looks like this:
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
type: 'OAuth2',
user: 'user#example.com',
clientId: '000000000000-xxx0.apps.googleusercontent.com',
clientSecret: 'XxxxxXXxX0xxxxxxxx0XXxX0',
refreshToken: '1/XXxXxsss-xxxXXXXXxXxx0XXXxxXXx0x00xxx',
accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x'
}
});
If you looked at the example in the link that I stated above, you can see there that there is a 'expires' property but in my code i didn't include it and it still works fine.
To get the clientId, clientSecret, refreshToken, and accessToken, I just watched this video https://www.youtube.com/watch?v=JJ44WA_eV8E .
I don't know if this is still helpful to you tho.
Gmail / Google app email service requires OAuth2 for authentication. PLAIN text password will require disabling security features manually on the google account.
To use OAuth2 in Nodemailer, refer: https://nodemailer.com/smtp/oauth2/
Sample code:
var email_smtp = nodemailer.createTransport({
host: "smtp.gmail.com",
auth: {
type: "OAuth2",
user: "youremail#gmail.com",
clientId: "CLIENT_ID_HERE",
clientSecret: "CLIENT_SECRET_HERE",
refreshToken: "REFRESH_TOKEN_HERE"
}
});
And if you still want to use just plain text password, disable secure login on your google account and use as follows:
var email_smtp = nodemailer.createTransport({
host: "smtp.gmail.com",
auth: {
type: "login", // default
user: "youremail#gmail.com",
pass: "PASSWORD_HERE"
}
});
We don't need to lower our Google Account Security for this. This works for me on localhost and live server. Versions: node 12.18.4, nodemailer ^6.4.11.
STEP 1:
Follow setting up your Google Api Access in this video AND IGNORE his code (it didn't work for me): https://www.youtube.com/watch?v=JJ44WA_eV8E
STEP 2:
Try this code in your main app file after you install nodemailer and dotenv via npm i nodemailer dotenv:
require('dotenv').config(); //import and config dotenv to use .env file for secrets
const nodemailer = require('nodemailer');
function sendMessage() {
try {
// mail options
const mailOptions = {
from: "MySite#mysite.com",
to: "my_gmail#gmail.com",
subject: "Hey there!",
text: "Whoa! It freakin works now."
};
// here we actually send it
transporter.sendMail(mailOptions, function(err, info) {
if (err) {
console.log("Error sending message: " + err);
} else {
// no errors, it worked
console.log("Message sent succesfully.");
}
});
} catch (error) {
console.log("Other error sending message: " + error);
}
}
// thats the key part, without all these it didn't work for me
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
service: 'gmail',
auth: {
type: "OAUTH2",
user: process.env.GMAIL_USERNAME, //set these in your .env file
clientId: process.env.OAUTH_CLIENT_ID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
refreshToken: process.env.OAUTH_REFRESH_TOKEN,
accessToken: process.env.OAUTH_ACCESS_TOKEN,
expires: 3599
}
});
// invoke sending function
sendMessage();
Your .env file for the above code should look similar to this:
GMAIL_USERNAME=your_mail#gmail.com
GMAIL_PASSWORD=lakjrfnk;wrh2poir2039r
OAUTH_CLIENT_ID=vfo9u2o435uk2jjfvlfdkpg284u3.apps.googleusercontent.com
OAUTH_CLIENT_SECRET=og029503irgier0oifwori
OAUTH_REFRESH_TOKEN=2093402i3jflj;geijgp039485puihsg[-9a[3;wjenjk,ucv[3485p0o485uyr;ifasjsdo283wefwf345w]fw2984329oshfsh
OAUTH_ACCESS_TOKEN=owiejfw84u92873598yiuhvsldiis9er0235983isudhfdosudv3k798qlk3j4094too283982fs
For me the issue was that I wasn't accessing the .env file variables properly (I assume you're storing your email and password in a .env file too). I had to add this to the top of the file:
const dotenv = require('dotenv');
dotenv.config();
Once I did that I could fill out the "auth" portion of the credentials like this:
auth: {
user: process.env.EMAIL_USERNAME,
pass: process.env.EMAIL_PASSWORD
}
Of course you need to replace EMAIL_USERNAME and EMAIL_PASSWORD with whatever you called those variables in your .env file.
For me it happened because I forgot to npm install dotenv and require('dotenv').config();
I came across this issue when deploying my app to Heroku. I was sending emails fine locally, but when I pushed a new build to Heroku, I got the dreaded Missing credentials for "PLAIN" error. My issue was that I hadn't separately setup the .env variables in Heroku.
If you go to your dashboard in Heroku, you can manually set up the config variables and that solved the problem for me.
Or you can do via Heroku CLI - good tutorial here
I was running ts-node in a folder that didn't have the .env file.
So my process.env.GMAIL_EMAIL and process.env.GMAIL_PASS weren't defined.
When I ran it in the directory with the .env, it worked
If you are going to use the basic authentication (your current configuration) you will need to activate less secure app access from the following link to your google account which was stated in node mailer site here.
Also for more secure way, I recommend to take a look on the two following links:
Sending Emails Securely Using Node.js, Nodemailer, SMTP, Gmail, and OAuth2 This will explain both simple/Basic and the secure methods to you.
Using OAuth2 in nodemailer official docs, which contain a more simplified version of the secure method (but you will need to follow the steps mentioned in the first link till you get the client_ID,client_Secret, Refresh_Token, and Access Token before proceeding with it).
Note: if you are going to use the secure way from the first link steps you should modify the auth attributes to add the type option like the following:
auth: {
type: 'OAuth2',
user: process.env.EMAIL,
accessToken,
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
refresh_token: process.env.REFRESH_TOKEN
}
because without stating explicitly that you are using OAuth2 method it will print the same error to you (based on my recent trials using the written code in that link)
This happened to me when I tried to send mail to MailHog, a development local mailserver which runs on port 1025, and uses no username/password by default.
My code was providing empty username/password, but in fact you should provide no credentials at all.
This does not work (results in 'Missing credentials for "PLAIN"'):
const transport = require('nodemailer').createTransport({
host: mailhog,
port: 1025,
secure: false,
auth: {
user: '',
pass: '',
},
});
But this works:
const transport = require('nodemailer').createTransport({
host: mailhog,
port: 1025,
secure: false,
});
For me it was because I forgot to add my Gmail password to my .env file.
Google disabled less secure apps, to resolve the issue one need to setup "Login with app password" and to allow the app password "setup two factor authentication"
when 2-Step-Verification is on and one get a "password incorrect" error, sign in to your account and go to security, try to use an App Password.
transport: {
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'contact#gmail.com',
pass: 'app password',
},
},
If you are expecting this (ERROR Send Error: Missing credentials for "PLAIN") error, it's probably because you are testing on localhost.
For example, if you are using Heroku, simply try to deploy your project and test it in production.
Regards.
I encountered the same problem, and that was caused by Google automatically blocked your logging-in form untruthful third-party software. Then you can just turn this feature off in your Google account management.
Regards,

mosquitto+mqtt.js got "Connection refused: Not authorized"

I built mosquitto on CentOS7 and a node.js client based on mqtt.js,installing with
yum install mosquitto mosquitto-clients
The local test
> mosquitto_sub -h localhost -t test
> mosquitto_pub -h localhost -t test -m "hello world"
works fine, but when I ran:
var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://192.168.1.70')
client.on('connect', function () {
client.subscribe('presence')
client.publish('presence', 'Hello mqtt')
})
client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString())
client.end()
})
I got Error: Connection refused: Not authorized
The mosquitto.conf is like:
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
allow_anonymous true
and I use systemctl restart mosquitto to restart it several time, which doesn't help. The firewall is down and log file stays empty.
A screenshot on status:
Can anyone help please?
UPDATE:
It turns out that the mosquitto service is somehow broken as the status shows Active: active (exited).
I use mosquitto -p 1884 -v cmd to run another mosquitto process on port 1884, it works fine. Then I try to reload the conf using
> /etc/init.d/mosquitto reload. It gives me
Reloading mosquitto configuration (via systemctl): Job for mosquitto.service invalid.
[FAILED]
So there IS something wrong with mosquitto service.
Not a final solution but I manage to fix this by remove-reboot-install process, the status went green as follow:
SOLUTION
I managed to find out the reason it doesn't work. I've installed rabbitmq on my server, it uses its "rabbitmq_mqtt" which consumes port 1883. Reassigning a port will solve this problem.
I managed to find out the reason. I've installed rabbitmq on my server, it uses its "rabbitmq_mqtt" which consumes port 1883. Reassigning a port will solve this problem. The problem is simple, but yeah, the CLI should have given me more information.
You need to add the authorize information to mqtt connect method.Just like this.
var client=mqtt.connect("ws://192.168.1.1", {
username: "yourUsername",
password: "yourPassword"
}
Add the Authorization details for the client to connect
var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://192.168.1.70', {
username: '<username>',
password: '<password>'
});
client.on('connect', function () {
client.subscribe('presence')
client.publish('presence', 'Hello mqtt')
})
client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString())
client.end()
})

nodemailer nodejs: sendmail exited with 127

I would like to send an email from my server (kimsufi), to confirm registration.
So, i use nodemailer https://github.com/andris9/Nodemailer
I have this error:
Error occured
Sendmail exited with 127
What's mean ?
Thanks !
If you are using this example
https://github.com/andris9/Nodemailer/blob/master/examples/example_sendmail.js
Then replace this code
var transport = nodemailer.createTransport("Sendmail",
"/usr/sbin/sendmail");
With
var transport = nodemailer.createTransport("SMTP", {
host: "smtp.gmail.com", // hostname
secureConnection: true, // use SSL
port: 465, // port for secure SMTP
auth: {
user: "foo#rcorp.co.in",
pass: "fooP#ssword"
} });
Make sure your sendmail path is correct. To check, open a terminal and issue:
which sendmail

Categories