How to normalize the input email? - javascript

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

Related

express-validator: Handling conditional validation

I have a form which takes the user email and password. I have setup validation with express validator which checks if the user email and password are empty and if email is a valid email as shown below.
const loginSchema = [
body("email")
.isEmail()
.withMessage("email must contain a valid email address")
.notEmpty()
.withMessage("please enter email"),
body("password").notEmpty().withMessage("please enter password"),
];
When testing in postman, if a user was to submit the form without entering email and password, it displays all error messages. How do I use conditionals with express validator to make it so that isEmail() withMessage is only called if the request body email is not empty?
From express-validator docs:
If the option onlyFirstError is set to true, then only the first error for each field will be included.
So you basically have to do this instead
validationResult(req).array({ onlyFirstError: true })
Alternatively, you can use the following to have the errors from a request be a map from field path to first error of that field:
validationResult(req).mapped()

Cognito user pool "username" appears as id not email, how to fix it?

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>

nodemailer sender is empty

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.

How do I improve this email address validation method?

I have a form called sub_form with 2 inputs, one of the inputs is an email address, the other is a choice from a dropdown menu. The Javascript below checks if the email address is valid, and also prints the values of both the inputs to the console log.
The problem is, when an incorrect email is entered, it shows the error message but still prints to the console.
How can I fix this so that the inputs only print to console if a valid email is entered?
<!-- validator -->
$('#sub_form').bootstrapValidator({live: 'disabled',
fields: {
email: {
validators: {
emailAddress: {
message: 'Invalid email' } }},}});
<!--print to console-->
document.getElementById('sub_form').onsubmit = function(){
console.log(document.getElementById('email').value);
console.log(document.getElementById('dropdown').value);
return false;
}
Per my comment on the question, this validation library as far as I've been able to tell is an older version of the one here. My company happens to use the same one, so I've been using that site a lot for reference. Just replace mentions of the "formValidation" method with "bootstrapValidator", and events use the "bv" namespace instead of "fv".
The validator should provide some methods for checking its valid state. You could use:
var validator = $('#sub_form').data('bootstrapValidator');
if (validator.isValidField('email')) {
console.log(document.getElementById('email').value);
}
See here for more info.

Meteor login email domain predefined

I want to make a Meteor app where users can only create an account if their email ends with #mydomain.com.
In the end, they would actually only need to enter their username and not the #mydomain.com part.
So, the create user field would look like:
Name: __________
eMail: __________#mydomain.com
Password: __________
Renter: __________
How would I go about doing this?
You use accounts package: meteor add accounts-password.
Then you would configure it in server-side code (http://docs.meteor.com/#accounts_config): Accounts.config({restrictCreationByEmailDomain:'mydomain.com'});
And then use Accounts.createUser in combination with custom UI that autofills the email domain part.
I'm assuming you're using Meteor's built-in accounts management packages. To limit signups to mydomain.com email addresses, put the following in server-side code:
Accounts.validateNewUser(function(user) {
if (/#mydomain\.com$/.test(user.emails[0].address.toLowerCase())) {
return true;
} else {
throw new Meteor.Error(403, "Email domain not allowed.");
}
});
As for helping them with adding the #mydomain.com, write some client-side code that validates the field in the login form where they enter their username. If it lacks an #, tack #mydomain.com onto the end of it before the form gets submitted.

Categories