I am trying to use nodemailer with an app that doesn't require any kind of verification. The server the app sits on has been whitelisted, so no username or password is required.
I setup my mail config as follows:
let mailConfig = {
pool: true,
maxConnections: maxConnections,
maxMessages: maxMessages,
rateDelta: rateDelta * 1000,
rateLimit: maxMessages * maxConnections,
secure: false,
ignoreTLS: true,
logger:true,
host: config.SMTP_Host,
port: config.SMTP_Port
};
However I keep bumping into a 550 error because the sender of the email isn't present. I found another stackoverflow question that states when you have a different host domain than the domain of the user (the user in this case being undefined) the sender automatically gets set to that. Which makes sense as to why my sender is being set to blank, even though I have in fact set it.
Is there a way to prevent nodemailer from changing the sender to match the user domain, if the user domain isn't present?
Or am I completely misunderstanding the error message?
So far I've tried to manually set these fields by doing this in the message object but I have to admit I'm not familiar with this type of protocol.
sender:config.SMTP_Host,
envelope: {
from: `"Sender Name" <${config.SMTP_Host}>`, // used as MAIL FROM: address for SMTP
to: `${email}, "${first_name}" <${email}>` // used as RCPT TO: address for SMTP
}
The from field must contain an email address not a hostname.
If we use gmail as an example what you're putting in the from field is
From: "Sender Name" <smtp.gmail.com>
When it should be:
From: "Sender Name" <sender#gmail.com>
The sending server is searching for "smtp.gmail.com" as a email and isn't finding it so you get a message saying the email address doesn't exist.
Related
I was working with express-validator when i encountered that i used normalize email for validation of email while signing up so i stored the normalized email to server.
Validation code:
router.post(
"/signup",
[
check("name").not().isEmpty(),
check("email").normalizeEmail().isEmail(),
check("password").isLength({ min: 6, max: 15 }),
],
userController.signupUser
);
Input email: abc.123#mail.com
normalized email: abc123#gmail.com (storing in db)
Now the problem is when working on login the input email doesn't matches and shows invalid credentials.
You just need to pass options inside normalizeEmail ():
normalizeEmail ({"gmail_remove_dots": false "})
After researching and observing I noticed that the code which was used at the time of signing up can be used to normalize email at the time of login, I just had to add:
router.post("/login",[check('email').normalizeEmail()], userController.loginUser);
After adding the email was converting to normalized one and can be used directly from requests.
You cannot remove any . or _ since it's part of the user's e-mail.
Here and example of validating an email address
I'm using Amazon Cognito user pools, and i choose to have users signup/In with their emails. According to online guides, when choosing so, the user pool should list users with "username" value as their email, but this is not the case, i'm seeing the "id" which is also referred to as "sub" as the "username" field!
it has the UUID format.
Any ideas how to get username shows the email?
** Note: I'm talking about showing users from AWS cognito console.
Attached is a screenshot
That seems to happen when you chose to signup with either email or phone.
Apparently in that configuration Cognito generates 'username' using the sub...
I would suggest configuring Congito to use 'username' and then on signup set up the 'username' to email, you can also pass email (and phone) as additional attributes.
I hope that helps
#Luke is correct, this only happens when you select the "Email address or phone number" option in the "How do you want your end users to sign in" section of the wizard.
It's a bit confusing because the SignUp API expects an email-formatted username during signup, but then ends up creating a user with a GUID as a username, and assigns the submitted username to the email attribute. This is described in the docs:
Call the SignUp API and pass an email address or phone number in the username parameter of the API. This API does the following:
If the username string is in valid email format, the user pool automatically populates the email attribute of the user with the username value.
If the username string format is not in email or phone number format, the SignUp API throws an exception.
The SignUp API generates a persistent UUID for your user, and uses it as the immutable username attribute internally. This UUID has the same value as the sub claim in the user identity token.
If the username string contains an email address or phone number that is already in use, the SignUp API throws an exception.
This is in fact probably what you want though, as it allows users to change their emails down the line (as actual usernames cannot be changed). And furthermore, the docs state that "You can use an email address or phone number as an alias in place of the username in all APIs except the ListUsers API", so the fact that the username is a GUID in the backend doesn't have much effect on how you interact with the API.
As for listing the email in the console, it looks like they've added an email column in the user list, so that shouldn't be a problem anymore.
Here you have an example.
auth.service.ts
you have to do the login method for Cognito in your authentication service. Something like this:
login(username: string, password: string): Promise<CognitoUser|any> {
return new Promise((resolve,reject) => {
Auth.signIn(username,password)
.then((user: CognitoUser|any) => {
this.currentUserSubject.next(user);
localStorage.setItem("currentUser", JSON.stringify(user));
localStorage.setItem("token", user.signInUserSession.idToken.jwtToken);
localStorage.setItem("userGroup", user.signInUserSession.idToken.payload['cognito:groups']);
localStorage.setItem("userEmail", user.attributes.email);
this.loggedIn = true;
resolve(user);
}).catch((error: any) => reject(error));
});
}
and then in the .ts of your component you have to do the call of that method in the constructor and store in a variable the userEmail argument that you get in the localStorage from Cognito:
constructor(
private authService: AuthService,
) {
this.authService.currentUser.subscribe(response => {
this.currentUser = response;
});
this.userSessionName = localStorage.getItem('userEmail');
}
Finally, you have to display the userSessionName variable in you .html component:
<p>{{ userSessionName }}</p>
When users register, some emails get into the spam folder.
I have two functions:
The first will make a configuration for nodemailer.
function sendingLetter() {
return nodemailer.createTransport({
service: config.transport.service,
secure: config.transport.ssl,
auth: {
user: config.transport.user,
pass: config.transport.password
}
});
}
The second is making a template for sending by mail with a link
function statusCheck(file, replacements) {
let html_file = fs.readFileSync(file, { encoding: 'utf-8' });
let template = handlebars.compile(html_file);
let htmlToSend = template(replacements);
return htmlToSend;
}
The function of sending letters to the user's mail
const smtpTransport = sendingLetter();
const confirm_email = path.join(__dirname, '../views/email_templates/users/confirm_email.html');
...
let rand_hash = Date.now();
let link = 'https://' + config.kHostName + '/api/users/verify/' + rand_hash;
let replacements = {
target_link: link,
};
let htmlToSend = statusCheck(confirm_email, replacements);
let mailOptions = {
from: config.transport.user,
to: user_email,
subject: Constants.users.messages.subjectConfimEmail,
html: htmlToSend,
};
smtpTransport.sendMail(mailOptions);
The template in which the link will be inserted to be sent to the user by mail
<p>
We're ready to activate your account. All we need to do is make sure this is your email address.
</p>
<a href="{{target_link}}"
<div class="butten">
Confirm Email
</div>
</a>
In some cases, Google sends my email to a spam folder. Why it happens? What are some tips to avoid this?
There is an algorithm within Google to categorize the messages according to your interest and have probably been categorized as undesirable.
The classification of messages sent from any website as spam is one of the most important things that a webmaster should pay attention to. I will discuss in this article what things a webmaster should pay attention to to ensure that messages sent by him Its website as spam (spam) ends up in a non-spam folder or spam folder.
How do service providers classify messages as spam?
The e-mail service providers use many methods and tools to filter the incoming e-mails of the system and accordingly decide whether or not the message should be classified as an annoying message.
Content-based filtering "Content Filters"
Filter based on the letterhead of the email "Email Header Filters"
Filter based on blacklists "Blacklist Filters"
Filter based on user decision "User Rule-based filters"
Methods of Solution
First: Filter based on Content Content Filters
Through which the content of the message and the method of writing it to find out whether the message is disturbing or not, by comparing the content to a database containing a set of words used in the spam and certainly every service provider has his own words in this area called " Spam Trigger Words, "and there are many lists of English words that can be found using the previous search term in the Google search engine.
Also, the service providers, through this mechanism, search the way in which the message was written, especially if the HTML code was used to write the message, then the service provider makes sure that the code written is a clean code.
The following are some tips that can be provided to avoid placing your message as spam based on the filtering mechanism based on the content:
Make sure that the title of the subject is not too long and not so short that it is just one word.
Make sure that the title or text of the message is not fully capitalized when writing in English.
Make sure that the message title does not contain Re: unless the message is actually in response to a message sent by the recipient.
Do not use a question mark in the message title.
You can use the $ $ sign in a sequential address or message content, for example, $$$.
When you write a message in HTML, do not use video, JavaScript or JavaScript in the message, and make sure that the HTML code is clean, standard and written correctly according to HTML standards.
Second: Liquidation Based on the letterhead "Email Header Filters":
Through this mechanism the server receives the message of the search for any false data can be found in the letterhead and accordingly classified as an annoying message or not.
Third: Liquidation based on blacklists "Blacklist Filters":
Blacklists are constantly updated databases that contain a list of IP addresses for servers that are based on or send spam messages.
Fourth: Liquidation based on the user's decision "User Rule-based filters":
Although this mechanism is not of great importance because it depends on the decision of the recipient of the message itself, but it must be mentioned, and in this mechanism the recipient of the message itself to indicate the message received as an annoying message and therefore in the following times to be written by the same address The message will go to the spam folder directly.
In the end I apologize for my relatively weak English.
I have a contact form using Nodemailer.
This is my code:
let mailOptions = {
from: '<xxx#xxx.com>', // sender address
to: 'xxx#xxx.com', // list of receivers
subject: 'Kontaktanfrage', // Subject line
html: output // html body
};
In the from I have set up my email but I actually want to see email from the user in my inbox.
Can someone help me to do it?
I would appreciate your help!
Node-mailer is used to send the messages you can also check this reference
there are other packages that works for you, you can check these, it might be your workaround
1.node-mailin
2. mailin
when receiving a message from pubnub, there is no information on the sender. how to know if it's a message from visitorA or visitorB ? there are examples on the web where the sender sends his name with the message, but how to know he isn't spoofing someone else's identity ?
here is an example of a chat interface :
<html>
<body>
<form id="message_form">
<input id="message_input" type="text"/>
</form>
<div id="chat"></div>
<script src="http://cdn.pubnub.com/pubnub-3.7.1.min.js"></script>
<script>
var pubnub = PUBNUB.init({
publish_key: 'demo',
subscribe_key: 'demo'
});
pubnub.subscribe({
channel: 'chat',
message: function(message){
var div = document.createElement("div");
div.textContent = message;
var chat = document.getElementById("chat");
chat.appendChild(div);
}
});
var form = document.getElementById("message_form");
form.onsubmit = function(e) {
var input = document.getElementById("message_input");
pubnub.publish({
channel: 'chat',
message: input.value
});
input.value = '';
e.preventDefault();
};
</script>
</body>
</html>
Chat User Identification
You can identify the sender by creating a Unique ID as well as a Name attached to the message payload of the chat conversation. This is similar to IRC strategies but a bit more simplistic.
var user_id = PUBNUB.uuid();
var user_name = name.value;
var user_message = input.vaule;
Here is a full example which includes the HTML elements for UserName input. Notice also that I added a safe_text() method to prevent XSS attacks.
<form id="message_form">
Name: <input id="name_input" value="John" type="text"/><br>
Message: <input id="message_input" value="Hi" type="text"/><br>
<input type="submit" value="send">
</form>
<div id="chat"></div>
<script src="http://cdn.pubnub.com/pubnub-dev.js"></script>
<script>
var userid = PUBNUB.uuid();
var pubnub = PUBNUB({
publish_key : 'demo',
subscribe_key : 'demo',
uuid : userid
});
function safe_text(text) {
return (''+text).replace( /[<>]/g, '' );
}
pubnub.subscribe({
channel: 'chat',
message: function(message){
var div = document.createElement("div");
div.textContent =
safe_text(message.name) + ": " +
safe_text(message.text);
var chat = document.getElementById("chat");
chat.appendChild(div);
}
});
var form = document.getElementById("message_form");
form.onsubmit = function(e) {
var input = document.getElementById("message_input");
var name = document.getElementById("name_input");
pubnub.publish({
channel: 'chat',
message: { name : name.value, text : input.value, userid :userid }
});
input.value = '';
e.preventDefault();
};
</script>
While this demonstration provides you with a quick and easy getting started app, you will want to add more enhanced chat security and chat authentication systems.
For additional resources for building chat applications check out Build Real-time Chat Apps in 10 Lines of Code guide and also Building A Basic Chat Application.
Chat Access Control Layer ACL
You will need to add Security ACL Access Control Layer. With PubNub Access Manager (PAM) you can control who has access by granting users permission with access tokens.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Grant Chat Access to Secured Conversations
// All server-side data is stored according to defined security policies.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
var pubnub = PUBNUB({
publish_key: "PUBLISH_KEY",
subscribe_key: "SUBSCRIBE_KEY",
secret_key: "SECRET_KEY"
})
pubnub.grant({
channel : "CHANNEL",
callback : receiver,
error : receiver,
ttl : 60, // Minutes
read : true,
write : true,
auth_key : "AUTH_KEY"
});
It is recommended to run this level of ACL code on Trusted Systems such as your own data center servers.
Sending/Receiving Secure Encrypted Messages
PubNub client libraries offer built-in Advanced Encryption Standard (AES) 256-bit encryption. To use message encryption, simply use cipher_key at initialization.
To enable Transport Layer Encryption with TLS and the ssl flag.
Then publish/subscribe as usual.
var pubnub = PUBNUB({
subscribe_key: 'sub-c-f762fb78-...',
publish_key: 'pub-c-156a6d5f-...',
ssl: true,
cipher_key: 'my_cipherkey'
});
Message Verification for Identity of Sender
Attaching user's information to each message is efficient and provides a very powerful level of flexibility within your application. However malicious users may attempt to spoof the identity of users and therefor impersonate other users. In the sample app we have shown that it is easy to impersonate anyone by changing your name in the "message_form" field. This is the same situation you encounter with email and SMTP where arbitrary email header impersonations are possible unless you provide a way to verify the identity of the sender. There is a solution! 😄
Digital Signatures are fingerprints with embedded secure cryptographic hashes of key components of the message payload optionally including a salt (sometimes a timestamp) and then signing/encrypting with an asymmetric secret key which is used to verify the identity of the sender. This process is used to block spoofers and impersonations.
A digital signature is a mathematical scheme for demonstrating the authenticity of a digital message or document.
Message Verification for Chat Applications
Start by assuming that only the chat users have been granted access and they can publish and subscribe to chat channels using grant and revoke techniques available in your PubNub Access Manager implementation.
The challenge here is that in a group chat room, your chat users have been granted auth_tokens yet they still can impersonate other chat users on the channel.
The goal here is to verify two things when a client receives a message.
Identity of sender.
Integrity of message.
Using asymmetric cryptography, you can provide a layer of validation and security to your users' messages by creating a digital signature. A valid digital signature gives a recipient reason to believe that the message was created by a known sender, that the sender cannot deny having sent the message (authentication and non-repudiation), and that the message was not altered in transit (integrity). Digital signatures are commonly used for financial transactions and message oriented communication such as email and chat and in other cases where it is important to detect forgery or tampering.
You will start by issuing each of your chat users' a set of keys, server generated, with a public-key (asymmetric) algorithm such as ECC/RSA via your server after user login. I recommend ECC as the key size is much smaller than RSA with comparable cryptographic strength. Each chat user in a chatroom is notified of other chat users' public key via a secured read only side-channel. Your users must only receive the Public Key from a public READ-ONLY channel controlled by your server's trusted and secure environment. Your server will be able to write each user's Public Key to this READ-ONLY channel. Your users will read from this channel.
Your user's can receive each other's Public Keys via a PubNub History call before joining the chat room. They should also open a subscription to the same channel to get public key of new chat users joining the chatroom.
The users' Private Key must not be exposed to anyone but the verified owner. This can be done upon email/password sign-on and you can send the private key to the verified user as soon as they log-in.
Sending a Chat Message with Attached Digital Signature
{ userId: 123456,
profilePic: "http://www.chats.com/user1234.jpg",
message: "Hello World",
signature: "tnnArxj06cWHq44gCs1OSKk/jLY" }
You will create the signature by concatenation of the following base string (userId+profilePic+message). Next you need to calculate a message digest using SHA1(signature_base_string) or SHA256(signature_base_string). Now you can use this cryptographically generated hash to sign with the users' private key using an ECC/RSA asymmetric algorithm.
Now attach this digital signature to chat message as shown in the example above and on to the final phase of Chatroom Message Verification.
Chatroom Message Verification
While subscribed to the chatroom channel you will receive user sent chat message with an attached digital signature. You will use this signature to verify the chat message's authenticity. If the message was an attempted spoof you will drop the message altogether.
// Digitally Signed Chat Message
{ userId: 123456,
profilePic: "http://www.chats.com/user1234.jpg",
message: "Hello World",
signature: "tnnArxj06cWHq44gCs1OSKk/jLY" }
To verify the signature you will create the signature by concatenation of the following base string (userId+profilePic+message). Next you need to calculate a message digest using SHA1(signature_base_string) or SHA256(signature_base_string). Now using the chat users' public key you already have for userId 123456 you can Verify/Decrypt digital signature to get original message digest you just generated which was also created by the sender.
Compare current message digest and original message digest. If they are the same then the message is authentic and you have successfully verified the sender's message using Message Verification via digital signing. If the digests do not match, it's a phony message and you may disregard the impersonator.
Creating a PKI Public Key Infrastructure using PubNub
You'll need a way to securely transmit public keys via a read-only PKI. PubNub provides to you a way for exposing a secure read-only PKI list for your chat users. Important to note that PKI requires asymmetric key algorithm like ECC or RSA. Also we are using these crypto algorithms for creating digital signatures rather than encrypting the data. This means we will be able to identify and verify the sender by successfully decrypting the signature using the public key and verifying the salted signed string matches.
Public Key is used as the Decryption Key and Verify Key.
Private Key is used as the Encryption Key and Signing Key.
It is important to note that you should only print the username retrieved from the Public Key Trusted Source and not from the message content. The message content is only used for signing and verifying Identity. If an Identity is changed it must be relayed via the PKI using PubNub’s Broadcast mechanism and Storage and Playback for Secure Authorization.
Access tokens, Identity Name/Photo and Asymmetric Keys must only be generated from trusted execution environments on your servers and relayed over PubNub's Authorized Read-only PKI data channels.
In the most recent PubNub SDKs (v4), the publisher UUID is now included in subscribe response.
{
actualChannel: null,
channel: "my_channel_1",
message: "Hello World!",
publisher: "pn-58e1a647-3e8a-4c7f-bfa4-e007ea4b2073",
subscribedChannel: "my_channel_1",
subscription: null,
timetoken: "14966804541029440"
}