i'm building a quizz app , which asks me to : Add user authentication: allow users to log in, and save their login credentials to local storage (HTML5 browser storage). what i want to add is to check if the user name && password (together, because you can have the same username and not the same password and vice versa), so i can prompt a "Welcome back (name of the user)".
i spent 3 days trying to figure out which logic works , tried everything but every time i get a logic problem where things doesn't go the way it should be , here's the code :
var usersinfo = {
users : []
}
localStorage.setItem("users", JSON.stringify(usersinfo.users))
function registerInfo(){
var name = document.forms[0].username.value;
var pw = document.forms[0].pw.value;
if (name === "" || pw === "") {
alert ('please complete all the forms')
} else {
var adding = JSON.parse(localStorage.getItem("users"));
// logic that goes here : i tried everything , looping...etc
}
return false;
}
Note that the function is attached to a button , and everything works fine on the HTML , the problem is in login logic .
Untested, but try something like this:
const users = JSON.parse(localStorage.getItem("users"));
if (users.some((user) => {
return user.name === document.forms[0].username.value;
})) {
alert('Welcome back!');
}
Basically, we use some on the array to loop through and figure out if any of the elements have the same name as the one from your form. If they do, we immediately stop looping and return true. If not, we return false.
See also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
And, do take #AnilRedshift's advice and don't store usernames/passwords in localstorage...
Related
Hello I am working a web application with Firebase Realtime Database and Authentication with nodejs or javascript.
This is my real time database and I want to make a login form which if the User = User he will go to User Index and if the User = Freelancer he will go to Freelancer Index.
And this is the line of code that I was tweaking or trying but It doesn't go in my way.
<script>
firebase.auth().onAuthStateChanged(function(user)
{
if(user)
{
var userID = firebase.auth().currentUser.uid;
firebase.database().ref('Users/' + userID).once('value').then(function(snapshot)
{
if (snapshot.val())
{
window.location.href = "index.html";
}
else
{
window.location.href = "okay.html";
}
});
}
});
</script>
Hoping I can get feedbacks or answers here. I am almost trying it for 2days already that's why I seek help here.
Comments and answers are highly appreciated thank you!
With your current data structure you will need to check in two places to determine what role a user has. While this technically possible, it is less efficient and more complex in code.
I recommend instead to store a single top-level node (say UserRoles) where you simply keep the role for each UID:
"UserRoles": {
"uidOfUser1": "Freelancer",
"uidOfUser2": "User"
}
With that in place, you can load it in your onAuthStateChanged callback with:
const ref = firebase.database.ref("UserRoles");
ref.child(user.uid).once("value").then((snapshot) => {
if (snapshot.val() === "Freelancer") {
window.location.href = "okay.html";
}
else if (snapshot.val() === "User") {
window.location.href = "index.html";
}
else {
alert("Can't determine role for user: "+user.uid)
}
});
I am trying to seperate two different logins for the different types of users that are in the account. One of the users is a regular consumer who is able to search through the app. The other is a business dashboard where businesses get to see what users are checkedin to their business.
The problem is that when I check my two different database references, it seems it checks both of them instead of validating the first check and proceeds to pull and error saying one of my nodes is null.
The case it apprently fails is the first if check but in my database the node userType is set properly:
The problem seems to be it auth().onStateChanged where it looks for the uid of in both database references. When I try to login with a business account it successfully enters that statement and redirects, when I log in with a consumer account it tries to check the business refs if and then pulls out the error userType is null cannot read
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// This prompts the user to allow for location access
// When logged in it would allow us to show the
// nearby businesses to the user
var uid = user.uid
if(window.navigator.geolocation) {
window.navigator.geolocation.getCurrentPosition(function(position){
})
}
var uid = user.uid
console.log(uid)
business.child(uid).on("value", snap => {
if(snap.val().userType == "business") {
alert("This is not a consumer account!")
firebase.auth().signOut()
window.location.href = "businesslogin.html"
} else {
consumer.child(uid).on("value", snap => {
if(snap.val().userType == "consumer") {
if(snap.val().isPhoneVerified == true) {
window.location.href = 'nearbyBusinesses.html'
} else {
window.location.href = 'loginVerification.html'
}
if(snap.val().isUserCheckedin == true){
window.location.href = "leave.html" + '#' + snap.val().checkedInBusinessId
} else {
window.location.href = "nearbyBusinesses.html"
}
}
})
}
})
}
})
The bug is in this line if(snap.val() == "business"). It needs to be if(snap.val().userType == "business"). Atleast that is what i can see imediately. Try that and see if it solves your problem
in my Dasboard Component i Need to Give a username and Send it
Form Server for Get Detail of User like fName , lName , Image , . . .
I Pass the username with this way :
when user is loggedin i u get the username from LocalStorage :
Login Component :
private usenameSource = new BehaviorSubject<string>('');
userName$ = this.usenameSource.asObservable();
getDecodedAccessToken(): any {
return jwt_decode(this.getRawAuthToken(AuthTokenType.AccessToken));
}
getUserNameDecode():any {
const decode = this.getDecodedAccessToken();
let userName = decode["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"];
return this.usenameSource.next(userName);
}
Dashboard Component :
this.loginService.userName$.subscribe((data) => {
this.userName = data;
})
Now, the problem is that when the browser is refreshing, the username will be null and I need to login again.
whats the problem ? how can i solve this problem ?
When the page refreshes, the "usenameSource" value will be cleared. To keep it, call your method "getUserNameDecode()" again in your service constructor.
constructor(...) {
this.getUserNameDecode();
}
getUserNameDecode():any {
const decode = this.getDecodedAccessToken();
if(!decode) {
// login failed
return;
}
let userName = decode["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"];
return this.usenameSource.next(userName);
}
....
I assume that Login Component will be loaded first when you start your application.
And also I assume that you are storing the userName details in local storage as soon as user logs in successfully.
So with that, we must check the userName in local storage first and based on that we must do the further operation.
Login Component
ngOnInit() {
const status = this.checkUserNameInLocalStorage();
if (status) {
this.userName = JSON.parse(window.localStorage['userName']);
} else {
// write your logic to get the userName details
}
}
checkUserNameInLocalStorage() {
if (window.localStorage['userName']) {
return true;
} else {
return false;
}
}
Hope this will help you.
I've got a form which is used to update a user's information, both in the Firebase JSON tree and the seperate database which holds the email + password combination for the users. Whenever you want to update either the email or password, you need to provide an email + password combination for it to work.
However, when you only want to update the JSON tree you can do it without a password. My form requires you to enter your current password before anything can happen, but if you type in the wrong password it will still update the display name of the user.
So my question is, is there a way that I can require the correct password before actually updating anything in the database?
The code in my controller:
//If the user has entered a new display name
if (sharedInfo.getUser().displayName !== $scope.user.displayName) {
var isNameChanged = userLogic.changeDisplayName($scope.user);
isNameChanged.then(function(isSuccessful) {
if (isSuccessful === true) {
$scope.isSuccessful = true;
}
else {
$scope.error = 'Update failed';
}
});
}
Function in my service:
changeDisplayName: function(user) {
//Get the user ID
var userData = sharedInfo.getAuthState();
return fbRef.getSyncedReference('users/' + userData.uid).$update({displayName: user.displayName}).then(function() {
return true;
}, function(error) {
return false;
});
}
I want to loop the local storage for the password and username to check if correct and alert a message if or if not.
The code is working well, but I don't know where to write the "invalid username" message because the loop goes through every record, so the messages pops ups for every record check until it finds it.
What I want is to pop up the message when the search is done.
Here is my code:
$("#login").click(function(){
var username =$("#user").val();
var password =$("#pass").val();
var userCount = localStorage.getItem('userCount');
for (i=1;i<=userCount;i++) {
var user = JSON.parse(localStorage.getItem("user" + i));
if((user.username == username)||(user.password == password)){
alert("welcome "+username);
} else {
alert("Invalid Username");//this message keeps poping up on every record until username found
}
}
});
Put the loop inside a function.
Return true (or the user object) from that function if anything inside the loop matched.
Return false after the loop (which you'll only reach if nothing matches).
Handle your alert outside the function based on the return value of calling it.
Set a boolean variable to true when you find a match, and stop the loop using break. Otherwise, if the boolean is still false after the loop completes, no match was found.
$("#login").click(function(){
var username =$("#user").val();
var password =$("#pass").val();
var userCount = localStorage.getItem('userCount');
var foundOne = false;
for (i=1;i<=userCount;i++) {
var user = JSON.parse(localStorage.getItem("user" + i));
if((user.username == username)&&(user.password == password)){
foundOne = true;
break;
}
}
if(foundOne) {
alert("welcome "+username);
// other "welcome" code
} else {
alert("Invalid Username");
}
});
NB, you may want to use the && operator instead of || here:
(user.username == username)&&(user.password == password)
otherwise you may get a match for one user who has the same password as another.