Nodemailer and "SSL23_GET_SERVER_HELLO:unknown protocol" error - javascript

Below is my Node.js code. Using the code results in:
Error: 0:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:openssl\ssl\s23_clnt.c:794
Here is the code:
var express = require('express')
, fs = require("fs")
, app = express()
, path = require('path')
, request = require('request')
, bodyParser = require('body-parser')
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server, {log: true, origins: '*:*'})
;
var smtpTransport = require('nodemailer-smtp-transport');
var options = {
key : fs.readFileSync('server.key'),
cert : fs.readFileSync('server.crt')
};
var nodemailer = require('nodemailer');
var sendmailTransport = require('nodemailer-sendmail-transport');
var emailserver = nodemailer.createTransport(smtpTransport({
service: 'Gmail',
port: 25,
strictSSL: false,
host:'smtp.gmail.com',
SSL Protocol: 'off',
TLS Protocol: ON,
auth: {
user: 'choudhary1707#gmail.com',
pass: 'mypassword'
},
tls: {ciphers: "SSLv3"}
}));
How to solve this error?

I had this error using a third party smtp with the 'nodemailer-smtp-transport' node module.
My problem turned out to be that I was using port 587.
When I switched it to 465 it all started working.
My configuration looks like:
const smtpConfiguration = {
host: '<my smtp host>',
port: 465,
secure: true, // use TLS
auth: {
user: '<user account>',
pass: '<password>'
}
};
And my email function (typescript, bluebird Promise):
export const SendEmail = (from:string,
to:string[],
subject:string,
text:string,
html:string) => {
const transportOptions = smtpConfiguration;
const transporter = nodemailer.createTransport(smtpTransport(transportOptions));
const emailOptions = {
from: from,
to: to.join(','),
subject: subject,
text: text,
html: html
};
return new Promise((resolve, reject) => {
transporter.sendMail(emailOptions, (err, data) => {
if (err) {
return reject(err);
} else {
return resolve(data);
}
});
});
};

I've faced similar problem
solved with this thread
// For port 465
var transporter = nodemailer.createTransport({
host: 'smtp.hostname',
port: 465,
secure: true,
auth: {
user: 'email',
pass: 'password'
}
});
// for port 587 or 25 or 2525 etc.
var transporter = nodemailer.createTransport({
host: 'smtp.hostname',
port: 587,
secure: false,
requireTLS: true, // only use if the server really does support TLS
auth: {
user: 'email',
pass: 'password'
}
});

Use this this is working
var nodemailer = require('nodemailer');
var smtpTransport = nodemailer.createTransport("SMTP", {
service: "Gmail",
connectionTimeout : "7000",
greetingTimeout : "7000",
auth: {
XOAuth2: {
user: "email id",
clientId: "client id",
clientSecret: "secret",
refreshToken: "refresh token"
}
}
});

Looks like your making it a little more complicated than it needs to be. I'm successfully using this with version 0.7.0 of Nodemailer.
var smtpTransport = nodemailer.createTransport("SMTP", {
service: "Gmail",
auth: {
user: "***#gmail.com",
pass: "****"
}
});
var mailOptions = {
from: "****#gmail.com",
to: to,
subject: 'Subject Line!',
text: 'Alternate Text',
html: '<label>Hello!</label>'
}
smtpTransport.sendMail(mailOptions, function(error, response) {
if (error) {
console.log(error);
} else {
console.log("Message sent: " + response.message);
}
// if you don't want to use this transport object anymore, uncomment following line
smtpTransport.close(); // shut down the connection pool, no more messages
callback();
});

Your problem is likely SSLv3. Most servers have it disabled.
TLS Protocol: ON,
auth: {
user: 'jdoe#example.com',
pass: 'super-secret-password'
},
tls: {ciphers: "SSLv3"}
You should use TLS 1.0 and above.
You should also use use Server Name Indication or SNI, but I don't know how to tell Node.js to use it.

Related

Nodemailer not sending email, displays "Message sent:Undefined"

It was working and then it wasn't. I sent a few mails and after a while it stopped working. I get
"Message sent:Undefined"
(node:9048) UnhandledPromiseRejectionWarning: Error: spawn sendmail ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:269:19)
I have no idea why.
Frontend- Axios console logs the response data therefore the server and the frontend both are working. It is just the issue with the Nodemailer.
Any help is appreciated. Thanks!
const express = require("express");
const app = express();
const cors = require("cors");
const nodemailer = require("nodemailer");
const path = require("path");
const fs = require("fs");
const readData = path.join(__dirname, "../email_take2/data.json");
const { v4: uuidv4 } = require("uuid");
app.use(express.json());
app.use(cors());
const port = process.env.PORT || 5000;
app.listen(5000, () => console.log(`Listening at port ${port}`));
if (process.env.NODE_ENV === "production") {
// Set static folder
app.use(express.static("../client/build"));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "../client", "build", "index.html"));
});
}
function listUserData() {
const data = fs.readFileSync(readData);
return JSON.parse(data);
}
app.post("/sendEmail", function (req, res) {
console.log(req.body);
const emailInfo = {
id: uuidv4(),
email: req.body.email,
cc: req.body.cc,
message:req.body.message,
};
const dataArray = listUserData();
dataArray.push(emailInfo);
fs.writeFileSync(readData, JSON.stringify(dataArray));
res.send(emailInfo);
console.log("SentBody", emailInfo);
let transporter = nodemailer.createTransport({
sendmail:true,
host: "smtp.outlook.com",
port: 587,
secure: false, // true for 465, false for other ports
tls: {
ciphers: "SSLv3",
},
auth: {
user: "memail#outlook.com", // generated ethereal user
pass: "mypw", // generated ethereal passwordAccount.pass,
},
});
// send mail with defined transport object
let info = transporter.sendMail({
from: '"Fred Foo 👻" <foo#example.com>', // sender address
to: "garbageacc7878#outlook.com", // list of receivers
subject: "Hello ✔", // Subject line
text: "Hello world?", // plain text body
html: "<b>Hello world?</b>", // html body
});
console.log("Message sent: %s", info.messageId);
return emailInfo;
});
transporter.sendMail returns a promise, that's why your console log has undefined. So either attach a .then and .catch.
transporter.sendMail(...)
.then((data)=>{console.log('Mail sent', data)})
.catch(err => {console.error('Failure',err)})
Or make your request handler an async function and use async await and use tryCatch.
try{
let data = await transporter.sendMail(...)
console.log('Mail sent', data)
} catch (err) {
console.error('Failure',err)
}

Nodemailer with email-templates not sending email

I'm using nodemailer with npm package email-templates. I'm not getting email. Template is working when i set preview:true. Getting error on console Error: No recipients defined.Why this error coming? Tried many things but nodemailer is sending empty email every time. Hope you understand my issue.
Error:
Error: No recipients defined
at SMTPConnection._formatError (E:\testing\node_modules\nodemailer\lib\smtp-connection\index.js:784:19)
at SMTPConnection._setEnvelope (E:\testing\node_modules\nodemailer\lib\smtp-connection\index.js:995:34)
at SMTPConnection.send (E:\testing\node_modules\nodemailer\lib\smtp-connection\index.js:615:14)
at sendMessage (E:\testing\node_modules\nodemailer\lib\smtp-transport\index.js:227:28)
at E:\testing\node_modules\nodemailer\lib\smtp-transport\index.js:285:25
at SMTPConnection._actionAUTHComplete (E:\testing\node_modules\nodemailer\lib\smtp-connection\index.js:1537:9)
at SMTPConnection.<anonymous> (E:\testing\node_modules\nodemailer\lib\smtp-connection\index.js:550:26)
at SMTPConnection._processResponse (E:\testing\node_modules\nodemailer\lib\smtp-connection\index.js:942:20)
at SMTPConnection._onData (E:\testing\node_modules\nodemailer\lib\smtp-connection\index.js:749:14)
at TLSSocket.SMTPConnection._onSocketData (E:\testing\node_modules\nodemailer\lib\smtp-connection\index.js:195:44)
at TLSSocket.emit (events.js:210:5)
at addChunk (_stream_readable.js:309:12)
at readableAddChunk (_stream_readable.js:290:11)
at TLSSocket.Readable.push (_stream_readable.js:224:10)
at TLSWrap.onStreamRead (internal/stream_base_commons.js:182:23) {
code: 'EENVELOPE',
command: 'API'
}
My directory structure:
├── app.js
└── emails
└── forget-password
├── html.pug
├── subject.pug
Node mailer with template:
const nodemailer = require('nodemailer');
var generator = require('generate-password');
const Email = require('email-templates');
exports.sendNodeForgotPasswordMail = function (email, GeneratePassword) {
var transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: 'my_email',
pass: 'my_password'
},
tls: {
rejectUnauthorized: false
}
});
const emailVar = new Email({
message: {
from: 'testing#gmail.com'
},
preview: true,
send: true,
transport: {
jsonTransport: true
}
});
emailVar.send({
template: 'forget-password',
message: {
to: email
},
locals: {
password: GeneratePassword
}
}) .then(res => {
console.log('res.originalMessage', res.originalMessage)
}).catch(console.error);
return transporter.sendMail(emailVar, function (err, info) {
if (err)
console.log(err);
else
console.log(info);
});
};
Html.pug:
p Your new password is: #{password}
subject.pug
= `Password reset request`
the reason is that you dont need to require nodemailer instead of make your transporter with nodemailer you need to pass it in JSON like so.
exports.sendNodeForgotPasswordMail = function (email, GeneratePassword) {
var transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: 'my_email',
pass: 'my_password'
},
tls: {
rejectUnauthorized: false
}
});
becomes:
transport: {
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: 'my_email',
pass: 'my_password'
},
tls: {
rejectUnauthorized: false
}
}
const Email = require('email-templates'); <-- with this is enough.
If anyone else is looking how to solve this, i manage to make it work based on #Irving Caarmal answer and the code is the following:
function sendTokenEmail(userEmail, token, templateName) {
const email = new Email({
message: {
from: 'someemail#gmail.com',
},
preview: true,
send: true,
transport: {
host: process.env.MAIL_HOST,
port: process.env.MAIL_PORT,
auth: {
user: process.env.MAIL_USER,
pass: process.env.MAIL_PASS,
},
},
})
return email
.send({
template: templateName,
message: {
to: userEmail,
},
locals: {
token,
},
})
.then((res) => {
console.log('res.originalMessage', res.originalMessage)
})
}
if anyone has an issue with getting on their email address the mail generated you should add at the level with send: true also the option preview: false (PS: this worked for me) without having the preview set to false the email would not come even if the docs say:
If you want to send emails in development or test environments, set options.send to true.
Example:
const email = new Email({
message: {
from: process.env.SMTP_USER,
},
send: true,
preview: false,
transport: {
host: process.env.SMTP_HOST,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
},
})
await email.send({
template: 'template-of-choice',
message: {
from: 'email-address'
},
locales: {}
})
Hope it helps :)

How correctly send email and close smtp connection in nodemailer?

In my Node.js application I use nodemailer library to send emails by SMTP.
As you can see from the code I have array called employees. That array has 2000 email address.
When I use code below application send only 10 email and then raise error Error: Invalid greeting. response=421 4.7.0 mailrelay1.***.** Error: too many connections from xxx.xx.xx.xxx.
It seems to me that every sending operation don't close the channel, even though I explicitly specified .close() method.
const express = require('express');
const nodemailer = require('nodemailer');
const forAsync = require('for-async');
let transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT, 10),
secure: false,
tls: {
rejectUnauthorized: false
}
});
const router = express.Router();
router.post('/employees', function(request, response) {
const employees = [***];
forAsync(employees, (employee) => {
return new Promise(resolve => {
// Setup email options.
const options = {
from: process.env.EMAIL,
to: employee,
subject: "System Alert",
html: html
};
return new Promise((resolve, reject) => {
setTimeout(() => {
transporter.sendMail(options, (error) => {
if(error) {
console.log(error);
reject(error);
} else {
resolve();
}
});
transporter.close();
}, 5000);
}).then(() => {
resolve();
}).catch(error => {
console.log(error);
});
});
});
});
You might want to look into sending a pool of emails.
To do this toggle the 'pool' option when you create your transport:
let transporter = nodemailer.createTransport({
pool: true,
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT, 10),
secure: false,
tls: {
rejectUnauthorized: false
}
});

NodeJS Setting a timeout for nodemailer

Made a small scrip that grabs a list of emails from another file. Then using the forEach to use the mail function from nodemailer to send an email to each of them. My problem is I want to have a timeout between each email sent. I have tried a couple of things and I am just purely stuck. If anyone could give me a hand. This is my first project trying to code lol.
'use strict';
const nodemailer = require('nodemailer');
var fs = require('fs');
//--------------------------------------------------------------------------
// Load Victims
//--------------------------------------------------------------------------
var victims = fs.readFileSync('./victims.txt', 'utf8').split("\r\n");
var letter = fs.readFileSync('./letter.txt', 'utf8');
victims.forEach(function(item, index, array) {
let transporter = nodemailer.createTransport({
pool: true,
maxConnections: 1,
maxMessages: 1,
rateDelta: 3000,
rateLimit: 1,
host: 'mail.asrebaziemast.com',
port: 587,
secure: false, // true for 465, false for other ports
tls: {
// do not fail on invalid certs
rejectUnauthorized: false
},
auth: {
user: "a1#asrebaziemast.com", // generated ethereal user
pass: "D#gician#d21" // generated ethereal password
}
});
let mailOptions = {
from: '"Freddy Mang" <a1#asrebaziemast.com>', // sender address
to: item, // list of receivers
subject: 'Hello ✔', // Subject line
html: letter, // html body
encoding: 'base64'
};
setTimeout(function () {
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log('Message sent: %s', info.messageId, item);
});
}, 5000);
});
The rateLimit / rateDelta options are what you want here, the problem is you are creating a new transporter instance per email.
Move the transport creation outside the forEach to reuse the same instance e.g.
const transporter = nodemailer.createTransport({
pool: true,
maxConnections: 1,
maxMessages: 1,
rateDelta: 3000,
rateLimit: 1,
host: 'mail.asrebaziemast.com',
port: 587,
secure: false, // true for 465, false for other ports
tls: {
// do not fail on invalid certs
rejectUnauthorized: false
},
auth: {
user: "a1#asrebaziemast.com", // generated ethereal user
pass: "D#gician#d21" // generated ethereal password
}
});
victims.forEach(item => {
transporter.sendMail({
from: '"Freddy Mang" <a1#asrebaziemast.com>', // sender address
to: item, // list of receivers
subject: 'Hello ✔', // Subject line
html: letter, // html body
encoding: 'base64'
}, (err, info) => {
if (err) {
return console.log(err);
}
console.log('Message sent: %s', info.messageId, item);
});
});

Issue with requiring of nodemailer in React.js;

I am trying to send an email after registration to a user. But I am having an issue with requiring of nodemailer module. I am getting the following error:
-The version of my npm is: 6.2.0
-The version of my node is: v8.11.1
-My package.json looks like this:
-My function for sending email looks like this:
sendEmail() {
var nodemailer = require("nodemailer");
nodemailer.createTestAccount((err, account) => {
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: 'example#gmail.com',
pass: 'example'
}
});
let mailOptions = {
from: '"Example" <example#gmail.com>',
to: this.inputEmail.value,
subject: 'Successful registration!',
text: "Thank you registing with us!"
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log("Message sent: %s", info.messageId);
console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
})
})
}

Categories