NodeJs and nodemailer - hide query parameters in the Email-Link and URL? - javascript

How can I hide the query-string parameters in the URL when sending an email to user with link and be able in the same time to read grab them when page is loaded in the browser?
Using: NodeJs, Angular1, MongoDb.
Code:
exports.newPass = function (req, res) {
User.findOne({
email: req.body.email
}, function (err, email) {
console.log('Email: ' + email);
if (err) throw err;
if (!email) {
console.log('Email: ' + email);
return res.json({ message: 'This Email does not exist!' });
}
var transport = mailer.createTransport({
host:'localhost',
port: 25,
secure: false,
auth: {
user: "userName",
pass: "passWord"
}
});
var mail = {
from: "DevOps <dev#localhost>",
to: "dev#localhost",
subject: "Set New Password",
text: "To set new Password: ",
html: '<strong>To set new Password: </strong>'
+ ' <a href="http://localhost:4000/endPoint#!/signup?m='
+ email.email
+ '&fn='
+ email.fullName
+ '&_id='
+ email._id
+ '">Restore Password</a>'
}
transport.sendMail(mail, function(error, response){
if(error){
console.log( 'Server Error: ' + error );
}else{
console.log( 'Message sent: ' + JSON.stringify(response.messageId) );
}
transport.close();
});
return res.json({ Ok: 'New Password will be send to you... please check your Emails' });
});
};
I'm able to manage this in the Angular Controller by adding the following:
$location.search({});
but the parameters and the values are still visible in the email-link.
They disappear after the user clicks on the email-link and goes to browser.
I would like to hide them also in the email which being sent to the recipient.

If safety is not a concern, you could create an object with the data you need, stringify it and then encode it in base 64. You can easily decode this back to the JSON string.
You'd do something like this in Node:
var data = { email: email.email, fn: email.fullName, _id: email._id };
data = JSON.stringify(data);
data = Buffer.from(data).toString('base64');
var mail = {
from: "DevOps <dev#localhost>",
to: "dev#localhost",
subject: "Set New Password",
text: "To set new Password: ",
html: '<strong>To set new Password: </strong>'
+ ' Restore Password'
}
Note that anyone can decode this back.
Depending on where you want to get this data back, you'd have to check different ways on how to decode this data. It's pretty similar in Node:
Buffer.from(b64string, 'base64');
However, if you don't want people to be able to decode this, then you'd have to take a different approach.
What I would do is generate a random hash, and store it in the database somewhere, indicating that it's connected to some user that wants a password change. You can then send that hash to the user, and look it up when the URL you sent is requested.

Related

TypeError - invalid login

I wrote some code to implement nodemailer in my nodejs application to send mails.
i wrote this code:
var express = require("express");
var router = express.Router();
var nodemailer = require("nodemailer");
/* GET contact page. */
router.get("/", function (req, res, next) {
res.render("contact", { title: "Contact" });
});
router.post("/send", function (req, res, next) {
var transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: "MyEmailHere",
pass: "password",
},
tls: {
rejectUnauthorized: false
}
});
var mailOptions = {
from: "MyEmailHere",
to: "myOtherEmailId",
subject: "Website Submission",
text:
"You have a new submission with the following details...Name: " +
req.body.name +
" Email: " +
req.body.email +
" Message: " +
req.body.message,
html:
"<p> You got a new submission with the following details...</p><ul></ul><li>Name: " +
req.body.name +
"</li><li>Email: " +
req.body.email +
"</li><li>Message: " +
req.body.message +
"</li></ul>",
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
res.redirect("/");
} else {
console.log("Message Sent: " + info.response);
}
});
});
module.exports = router;
But I get an error saying: "Username and password not accepted." Am i supposed to use my real password? Does nodemailer also support Yahoomail besides Gmail? I am still learning and in dev mode by the way. A little help?
It worked flawlessly when I entered my own information correctly and turned on 'less secure apps', please try it this way
NOTE (critical): make sure the 'less secure apps' option is turned on
(If you don't know how to open, you can visit here)
NOTE: Make sure 2-step verification is turned off
var express = require("express");
var router = express.Router();
var nodemailer = require("nodemailer");
const myGmailAccount = {
mail: 'your_gmail_address', // MAIL
passw: 'your_gmail_password', // PASSW
};
/* GET contact page. */
router.get("/", function (req, res, next) {
res.render("contact", { title: "Contact" });
});
router.post("/send", function (req, res, next) {
var transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: myGmailAccount.mail,
pass: myGmailAccount.passw,
},
tls: {
rejectUnauthorized: false
}
});
var mailOptions = {
from: myGmailAccount.mail,
to: 'emintayfur#icloud.com', // recipient mail
subject: "Website Submission",
text:
"You have a new submission with the following details...Name: " +
req.body.name +
" Email: " +
req.body.email +
" Message: " +
req.body.message,
html:
"<p> You got a new submission with the following details...</p><ul></ul><li>Name: " +
req.body.name +
"</li><li>Email: " +
req.body.email +
"</li><li>Message: " +
req.body.message +
"</li></ul>",
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
res.redirect("/");
} else {
console.log("Message Sent: " + info.response);
}
});
});
Yes, you need to enter your real information and I recommend you to read this text.
Even though Gmail is the fastest way to get started with sending
emails, it is by no means a preferable solution unless you are using
OAuth2 authentication. Gmail expects the user to be an actual user not
a robot so it runs a lot of heuristics for every login attempt and
blocks anything that looks suspicious to defend the user from account
hijacking attempts. For example you might run into trouble if your
server is in another geographical location – everything works in your
dev machine but messages are blocked in production.
Additionally Gmail has came up with the concept of “Less Secure” apps which is
basically
anyone who uses plain password to login to Gmail, so you might end up
in a situation where one username can send mail (support for “less
secure” apps is enabled) but other is blocked (support for “less
secure” apps is disabled). You can configure your Gmail account to
allow less secure apps here. When using this method make sure to also
enable the required functionality by completing the “Captcha Enable”
challenge. Without this, less secure connections probably would not
work.
And make sure the 'less secure apps' option is turned on
If you don't know how to open, you can visit here
For more information I suggest you to review this page

Cannot POST /contact - but no where in my code do I request that post

I'm trying to create a contact box with nodemailer and everything worked at first. I console.logged(error) or "success" and received the email where it was supposed to go and also received my console "success" message. However, when I go to render a physical "success" message that the user can see, I receive the error cannot POST /contact. The weird thing is I don't have the post request going to /contact. I've been looking at the code for a while so it could be something simple, but I'm at a loss. I appreciate any help.
I've tried to render the homepage, declared a variable and put that variable onto the webpage to display for the user then I just tried displaying the home page and still receiving the same error. *I've left some critical information blank as I'm doing this on my local system before I push it to Heroku.
app.post('/', function(req, res) {
let mailOpts, smtpTrans;
smtpTrans = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: '',
pass: ''
}
});
mailOpts = {
from: req.body.name + ' <' + req.body.email + '>',
to: '',
subject: 'New message from contact form',
text: `${req.body.name} (${req.body.email} ${req.body.nbr}) says: ${req.body.msg}`
};
smtpTrans.sendMail(mailOpts, function (error, response) {
if (error) {
console.log(error);
} else {
res.render('/');
}
});
});
Change / to /contact:
app.post('/contact', function(req, res) {...});

how to send encrypted message via nodejs?

I am sending emails via postfix mail server.
the code is on node.js using sendmail:
const sendmail = require('sendmail')({
logger: {
debug: console.log,
info: console.info,
warn: console.warn,
error: console.error
},
silent: true,
smtpPort: 25, // Default: 25
dkim: {
privateKey: fs.readFileSync('mail_key.txt', 'utf8'),
keySelector: 'mail'
},
smtpHost: 'mail.mydomain.com' // Default: -1 - extra smtp host after resolveMX
})
const text = 'some text .... ';
var mes=sendmail({
from: ' "some sender" <info#mydomain.com',
to: data.Email,
subject: 'Your Account Data',
html:text,
}, function(err, reply) {
console.log(err && err.stack);
console.dir(reply);
});
messages are send successfully. but still is encrypted.
i want to know how to send emails to be encrypted.
BTW my connection is encrypted using TLS‌ before. I want to encrypt message content.
You can use bcrypt package to encrypt your string value and here is how you can use it:
let text2 = 'some....';
bcrypt.hash(text2, 10, (err, hash) => {
if(err) throw err;
text = hash;
console.log('happy hashing',text);
});

Parse Server how to access token for password reset

I am using Parse Server and have setup the config options to use a custom page for the password reset. This works fine, when you click the password reset link it takes you to my custom page.
The query parameters on the URL give me the username and a token. My plan was to use the username to query the User Class and get the user, and then get the token associated with the user to see if it matched the token in the URL.
My problem is I can't find where that token is — I do not see it in Parse Dashboard when I browse the User Class. And when I try to access it via a User query it comes back undefined (as I would expect since it's not there).
Here's some example code I put in my React component:
const { token, username } = this.props.queryParams
console.log('username from URL query params: ' + username)
console.log('token from URL query params: ' + token)
const User = Parse.Object.extend('User')
const userQuery = new Parse.Query(User)
userQuery
.equalTo('username', username)
.first()
.then(
function(user) {
console.log('Returned username: ' + user.get('username'))
console.log('Returned token: ' + user.get('token'))
},
function(error) {
console.log('Error:')
console.log(error)
}
)
Which logs this:
username from URL query params: davidhank
token from URL query params: veKHpzVgFEFCHdqfkXphz5DpD
Returned username: davidhank
Returned token: undefined
My question: Where does Parse store this token?

unable to send html text using nodemailer

I am unable to send html text in mail using nodemailer.
exports.send = function(req, res) {
console.log(req.query);
var mailOptions = {
to: req.query.email,
subject: req.query.sub,
text: 'Date of Interview: ' + req.query.dateOfInterview+ 'Time of Interview: ' + req.query.timeOfInterview + '' + req.query.assignedTechnicalPerson + '' + req.query.typeOfInterview + '' + req.query.interviewLocation
}
smtpTransport.sendMail(mailOptions, function(error, response) {
if (error) {
console.log(error);
res.end("error");
} else {
console.log("Message sent: " + response.message);
res.end("sent");
}
});
};
I am getting mail as continuous text without any line space
How can i send the same text using html tags in it i have also tried keeping html and end up getting lots of errors
Please say me correct syntax
Any help is appreciated
Here is the working code with nodemailer latest version.
var smtpTransport = require('nodemailer-smtp-transport');
var transporter = nodeMailer.createTransport(
smtpTransport({
service: 'gmail',
auth: {
user: <Your gmail>,
pass: '*****'//ur password
}
})
);
transporter.sendMail({
from: 'sender#gmail.com',
to: "recipient#mail.id",
subject: 'hello world!',
//text:"one"
html: '<html><body>Hello World....</body></html>'
}, function(error, response) {
if (error) {
console.log(error);
} else {
console.log('Message sent');
}
});
Note: To give access for smtp do the following:
For Gmail you may need to configure "Allow Less Secure Apps" in your
Gmail account. Click here
You also may need to unlock your account with "Allow access to your
Google account" to use SMTP.
If you are using 2FA in that case you would have to create an
Application specific password.

Categories