Asynchronously checking if email is taken already using AngularJS - angularjs

I have the following email field for taking user input for email. Once the email has been entered and focus is taken away from the field ng-blur triggers the function that checks whether the email entered by the user has already been taken:
<input type="email" class="form-control" placeholder="" ng-model="email" name="email" required ng-blur="isFound(email)">
To show the error I've got the following span:
<span class="help-block error" ng-show="blurred && isTaken">Email is taken already</span>
And here is the function isFound(email):
$scope.isFound = function(email) {
service.isEmailTaken(email).then(function(data) {
console.log(data); //this shows either null or the returned data
$scope.blurred = true;
if(data == null) {
$scope.isTaken = false;
} else {
$scope.isTaken = true;
}
});
}
Now when I try an email that has been taken, it shows the message correctly. But after that even when I enter the email that has not been taken it keeps showing the same message that the Email is taken already.
Could somebody help me understand the reason why is it happening and how to resolve it?
EDIT - Adding AngularJS and NodeJS/ExpressJS/Mongoose code below:
AngularJS
factory.isEmailTaken = function(email) {
return $http({url: "/api/queries/email/" + email, method: "GET"}).then(function(resp) {
return resp.data;
});
};
ExpressJS/NodeJS/Mongoose
app.get('/api/queries/email/:email', function (req, res) {
Query.findOne({email: req.params.email}, function (err, query) {
if (err)
res.send(err);
res.json(query);
});
});

When the email was not taken already value of data was null, and the typeof data was String.
The reason why it was not working earlier was because if(data == null) was always turning out to be false.
if(data == 'null') got things working properly.

Related

canceling http request in angular 1.5

We are making an HTTP request based upon user input. So each time the user inputs a character, an HTTP request is kicked off. The issue we are having: the user will enter ABC and then enter ABCD. ABCD will respond before ABC. Thus, the displayed results do not match ABCD. They match ABC.
Below is our current solution. We are rejecting all promises that have not been resolved. This seems to me to be an anti-pattern. Is there an approach to this that will result in better performance, readability, or better functionality?
function cancelPreviousSearchRequest(previousSearchRequest) {
if(previousSearchRequest) {
previousSearchRequest._defer.resolve();
}
}
function getPVendors(typed, subTypes) {
var pVendorsDefer = $q.defer();
var pVendorsPromise = pVendorsDefer.promise;
$http.get(SERVLET_CONTEXT + RestConstants.masterDataIntegrationSearchByPvendorName(typed, subTypes), {timeout: pVendorsPromise})
.success(function(data){
var result = _.get(data, '_embedded.paymentVendors', []);
pVendorsDefer.resolve(result);
})
.error(function(data){
if(data != null) {
growl.error("Service error occurred while retrieving Payment Vendors");
}
pVendorsDefer.reject();
});
pVendorsPromise._defer = pVendorsDefer;
return pVendorsPromise;
}
NOTES FROM COMMENTS:
We are doing a debounce already: ng-model-options="{ debounce: 150 }"

Firebase - issue with Auth during registration

I am new to firebase and have managed to successfully setup an authentication with email/ password based off what I have managed to gather from the documentation/ examples online. I've encountered some strange behaviour on register though. First of all here is my firebase auth code that sits in a React component function:
class SignupComponentInner extends Component {
toggleSignupLayoverAction(event){
this.props.toggleSignupLayover("false")
}
signUp(e) {
e.preventDefault();
var firstName = $('.signup-first-name').val();
var lastName = $('.signup-last-name').val();
var userName = $('.signup-user-name').val();
var password = $('.signup-user-password').val();
var email = $('.signup-email').val();
var auth = firebase.auth();
const promise = auth.createUserWithEmailAndPassword(email,password).then(function(user) {
var user = firebase.auth().currentUser;
user.updateProfile({
displayName: userName,
}).then(function() {
// Update successful.
// new db code here
firebase.database().ref('users/' + user.uid).set({
firstName: firstName,
lastName: lastName,
userName: userName
})
// end new db code here
}, function(error) {
// An error happened.
});
}, function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// [START_EXCLUDE]
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
} else {
console.error(error);
}
// [END_EXCLUDE]
});
promise.catch(e => console.log(e.message));
firebase.auth().onAuthStateChanged(firebaseUser => {
if(firebaseUser) {
console.log("logged in");
var sendUserId = firebaseUser.uid;
this.props.logUserIn(sendUserId)
} else {
console.log("not logged in")
}
});
}
render() {
return (
<div onClick={this.toggleSignupLayoverAction.bind(this)} className="signup-cont-par">
<div className="signup-component-inner">
<div className="signup-component-content" onClick={cancelBubble.bind(this)}>
<h2>Sign up today!</h2>
<form className="signup-form-elem">
<input placeholder="First Name" className="signup-first-name" type="text"></input>
<input placeholder="Last Name" className="signup-last-name" type="text"></input>
<input placeholder="Username" className="signup-user-name" type="text"></input>
<input placeholder="Password" className="signup-user-password" type="password"></input>
<input placeholder="Email Address" className="signup-email" type="text"></input>
<button onClick={this.signUp.bind(this)}>Sign Up</button>
</form>
</div>
</div>
</div>
)
}
}
So the registration part works exactly as it should but its the login part here that is causing issues:
firebase.auth().onAuthStateChanged(firebaseUser => {
if(firebaseUser) {
console.log("logged in");
var sendUserId = firebaseUser.uid;
this.props.logUserIn(sendUserId)
} else {
console.log("not logged in")
}
});
It's basically executing twice as im getting console.log "logged in" twice on register. Not sure why that is?
The other issue is the function that it is calling from the props this.props.logUserIn(sendUserId) This function basically hides a "create account" CTA and replaces it with a hello {{username}}. The username updates on register but very strangely it will update to whatever username I registered on the previous register! Here is the logUserIn function if it helps:
logUserIn(userId) {
var db = firebase.database();
var ref = db.ref('/users/' + userId);
console.log(userId);
ref.once('value').then((snapshot) => {
var userObject = snapshot.val();
var loggedUserName = userObject.userName;
this.setState({
LoggedInUsername:loggedUserName
})
});
this.setState({
loggedInState:true,
LoggedInId:userId,
signingUp:"inactive"
})
},
Here loggedUserNameis a state that is passed down to the main component to show the username that has just been registered (the one that is incorrectly showing the previous registered person when it should be showing the latest). Not sure where I have gone wrong.
Firebase maintains persistent connections with their servers so if you registered once, Firebase detects your browser and machine to be logged in for that newly created user. So, if you close the browser and then come back to your project on the SAME browser, Firebase still thinks you are logged in and hence, the onAuthStateChanged event handler is called.
Try it out for yourself and see what happens when you open up 2 different browsers.
To complete the whole authentication system, you need to have a logout function that will tell Firebase that this user has logged out (https://firebase.google.com/docs/auth/web/password-auth#next_steps)

Programm flow is behaving abnormal in angularjs

I am using angular js mvc ie. ui,controller and service. I have written a code that checks whether the same name organization is present in the database or not.
For this purpose I have written an AJAX call. which return me if the name is present in the database or not in the form of '0' or '1'.
ie.'1' for present and '0' for absent. I check this response in the controller and then if the response is one I am returning false to the calling function, but even though everything goes right I still get to see the variable value as 'undefined'.
Following is the code:
controller:
$scope.checkOrgName = function(){
console.log("We are checking id organization name "+$scope.organization.orgName+" is already present in the database or not");
if($scope.organization.orgName != ""){
OrganizationService.checkOrgName($scope.organization.orgName).then(
function(data){
var dbOrgName = data;
if(dbOrgName==1){
(Command comes here and shows the following alert box on the UI)
$scope.failureAlertMessage("This organization name is already present, enter some other name");
$scope.organization.orgName = "";
return false;(here I am returning false)
}
else if(dbOrgName==0){
console.log("Organization name is available");
return true;
}
},
function(errResponse){
$scope.failureAlertMessage("Error while checking organization name in the database");
}
);
}else{
console.log("No need for the organization name checking, name empty");
}
}
calling function (within controller only)
(Here I am calling the above function)
$scope.orgNameStatus = $scope.checkOrgName();
console.log("$scope.orgNameStatus: "+$scope.orgNameStatus);(This line prints 'undefined')
if($scope.orgNameStatus == false){
return false;
}
Browser Console:
Inside addOrganization
organization_controller.js:51 We are checking id organization name dsd is already present in the database or not
organization_service.js:25 In service: check org name
organization_controller.js:171 $scope.orgNameStatus: undefined
organization_controller.js:217 Validation status: true
organization_controller.js:59 Command in dbOrgName==1
What is wrong with code. Please help me, Thank you.!!
The reason why $scope.orgNameStatus is undefined is that your function $scope.checkOrgNamedoes not return any value. You only have a return statement within the then callback of the function.
In any case, since the function is asynchrounous, it will only return a Promise on which you can register a callback again. You need to make sure that the request is complete before you continue your processing.
Controller
$scope.checkOrgName = function(){
console.log("We are checking id organization name "+$scope.organization.orgName+" is already present in the database or not");
if($scope.organization.orgName != ""){
// added return statement to return promise
return OrganizationService.checkOrgName($scope.organization.orgName).then(
function(data){
var dbOrgName = data;
if(dbOrgName==1){
(Command comes here and shows the following alert box on the UI)
$scope.failureAlertMessage("This organization name is already present, enter some other name");
$scope.organization.orgName = "";
return false;(here I am returning false)
}
else if(dbOrgName==0){
console.log("Organization name is available");
return true;
}
},
function(errResponse){
$scope.failureAlertMessage("Error while checking organization name in the database");
}
);
}else{
console.log("No need for the organization name checking, name empty");
}
}
Calling function
$scope.checkOrgName().then(function(status) {
$scope.orgNameStatus = status; // now the request is complete and we can assign the status to the scope variable
console.log("$scope.orgNameStatus: "+$scope.orgNameStatus);(This line prints 'undefined')
if($scope.orgNameStatus == false){
return false;
}
});

Login mechanism using AngularJS

Hi in my application login is working fine but one problem is for example my password is- secret if i enter SECRET with capital or SEcret also it is logging in, If i give wrong password it will return false any solution
Login Controller
app.controller('LoginController',function(loginService, $rootScope,$scope, $http,$location) {
$scope.login = function () {
$scope.log=loginService.getLogin( $scope.emailId , $scope.password).
then(function (response) {
console.log($scope.log);
console.log(response)
if (response.data.LoginVerificationResult.length === 0) {
alert('details are not Available for this emailId');
$scope.error=true;
} else {
$rootScope.name=response.data.LoginVerificationResult[0].UserName;
$scope.abc=response.data.LoginVerificationResult[0].UserType
console.log($scope.abc+"from.......");
sessionStorage.setItem("EmaiId",$scope.emailId);
sessionStorage.setItem("User Id",response.data.LoginVerificationResult[0].UserID);
sessionStorage.setItem("UserName",response.data.LoginVerificationResult[0].UserName);
sessionStorage.setItem("UserType",response.data.LoginVerificationResult[0].UserType);
$scope.UserType = sessionStorage.getItem("UserType");
console.log($scope.UserType +"from login controller")
if ($scope.UserType =='Hr') {
$location.path('/empRegister')
}
else if ($scope.UserType =='Admin') {
$location.path('/patientRegister')
}
else {
$location.path('/dashboard')
}
}
});
};
});
All scenarios are working fine but problem is with password mentioned above
The password matching is happening server-side.
Currently is set to match your passwords in a case-insensitive way. You should change this to match case-sensitive passwords

hashing password in meanjs

I'm reading source code of meanjs and my question is the hashPassword method with the code:
UserSchema.methods.hashPassword = function(password) {
if (this.salt && password) {
return crypto.pbkdf2Sync(password, this.salt, 10000, 64).toString('base64');
} else {
return password;
}
};
Here I can't understand why it is returning password, in case this.salt && password is false? As I understand, that is a problem and perhaps it should stop saving the user, right?
Directly before the hashPassword function defintion, you should see this block:
/**
* Hook a pre save method to hash the password
*/
UserSchema.pre('save', function(next) {
if (this.password && this.password.length > 6) {
this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
this.password = this.hashPassword(this.password);
}
next();
});
As you can see, a salt is generated right before hashPassword is called. If you are using meanjs properly, the plain password will never be returned. If salt is undefined for any reason, instead of throwing an error it continues and saves the password in plain text.
I had some issues with this method and change it to this
if (this.password && this.password.length > 6) {
if (!this.salt || this.salt.length === 0) {
this.salt = crypto.randomBytes(16).toString('base64');
this.password = this.hashPassword(this.password);
}
}
The bug is that if you ever try to save user again after initial save you will not be able to login with that user details.
What would happen it would use salt to encrypt already encrypted password which is in my opinion is wrong.
So two options to handle that issue one is that you always set user password to empty string before you call save or you do what I did or something along those lines.

Resources