Email:
Invalid email!
Password:
Password need 10 characters!
Submit
I would suggest you to do a serverside authentication, but if you are practicing the authentication from mockdata then you can do the following on your onSubmit:
onSubmit(): void {
var res = this.authservice.admins.filter(data => data.email === this.model.email && data.password === this.model.password);
if (res.length > 0) {
this.authservice.adminFull = true;
this.authservice.isUserLoggedIn = true;
this.route.navigate(['/dashboard']);
this.text = null;
}else{
//do whatever you want for unauthenticated
alert('user not found');
}
}
Related
the problem is, I am not able to make a request to MongoDB after validating the request with the following code:
module.exports.validateRegisterInput = (
username,
email,
password,
confirmPassword
) => {
const errors = {};
if (username.trim() === "") {
errors.username = "Username must be provided";
}
if (email.trim() === "") {
errors.email = "Email must be provided";
} else {
const validEmail =
/^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*#([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$/;
if (!email.match(validEmail)) {
errors.email = "Email must be valid";
}
}
if (password === "") {
errors.password = "Password must be provided";
}
if (password !== confirmPassword) {
errors.password = "Passwords must match";
}
return {
errors,
vaild: Object.keys(errors).length < 1,
};
};
the validators work fine and check the request for any mistakes but once there is no issue with the request it does not let me send a request and raises an error anyway, also I am using the validators in the following way:
module.exports = {
Mutation: {
async register(
parent,
{ registerInput: { username, email, password, confirmPassword } }
) {
const { valid, errors } = validateRegisterInput(
username,
email,
password,
confirmPassword
);
if (!valid) {
throw new UserInputError("Errors", { errors });
}
...
so, I solved the problem, the problem was I was not calling the question directly and changed it to:
validateRegisterInput(username, email, password, confirmPassword);
and add errors in the validators and not in the index
const { UserInputError } = require("apollo-server");
module.exports.validateRegisterInput = (
username,
email,
password,
confirmPassword
) => {
if (username.trim() === "") {
throw new UserInputError("Username must be provided", {
errors: {
username: "Username must be provided",
},
});
}
if (email.trim() === "") {
throw new UserInputError("Email must be provided", {
errors: {
email: "Email must be provided",
},
});
} else {
const validEmail =
/^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*#([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$/;
if (!email.match(validEmail)) {
throw new UserInputError("Email must be correct", {
errors: {
email: "Email must be correct",
},
});
}
}
if (password === "") {
throw new UserInputError("Password must be provided", {
errors: {
password: "Password must be provided",
},
});
}
if (password !== confirmPassword) {
throw new UserInputError("Passwords must match", {
errors: {
password: "Password must match",
},
});
}
};
My problem is to add data to the database by taking the information from a form.
I want to add the information as "name". I can add "email" correctly but not other data.
My code:
buttonsignup.addEventListener('click', error => {
var nameCompany = document.getElementById('nameCompany').value;
var email = document.getElementById('email').value;
});
function add(nameCompany,email) {
firebase.database().ref().child('users_company').push({
nameCompany: nameCompany,
email: email
});
}
function intFirebase () {
/*CURRENT USER*/
firebase.auth().onAuthStateChanged(function(user) {
if (user != null) {
console.log(user);
console.log('El UID es '+user.uid);
add(nameCompany,user.email);
} else {
console.log('No user is signed in.');
}
});
}
window.onload = function() {
intFirebase();
}
Okay, After turning the coffee into code. I found this solution. But ... Is it a good practice?
const database = firebase.database();
var user = firebase.auth().currentUser;
/* BOTON SIGNUP */
buttonsignup.addEventListener('click', error => {
var nameCompany = document.getElementById('nameCompany').value;
var email = document.getElementById('email').value;
var password_1 = document.getElementById('password_1').value;
var password_2 = document.getElementById('password_2').value;
if (password_1 == password_2) {
if (password_1.length < 8) {
console.log('ContraseƱa muy corta');
document.getElementById("errorPassword").innerHTML = "8 characters";
} else {
firebase.auth().createUserWithEmailAndPassword(email, password_1).then (function(result) {
add(nameCompany,email);
}).catch(function (error) {
var errorCode = error.code;
var errorMessage = error.message;
};
});
}
} else{
console.log('errorPassword');
}
});
function add(nameCompany,email) {
firebase.database().ref().child('users_company').push({
nameCompany: nameCompany,
emailCompany: email
});
}
function intFirebase () {
/*CURRENT USER*/
firebase.auth().onAuthStateChanged(function(user) {
if (user != null) {
console.log(user);
console.log('El UID es '+user.uid);
} else {
console.log('No user is signed in.');
}
});
}
window.onload = function() {
intFirebase();
}
And database rules
{
"rules": {
"users_company": {
"$uid": {
".read": "auth != null && auth.uid === $uid",
".write": true,
//Change this code to: I can not do scripts in the database. -> ".write": "auth != null && auth.uid === $uid",
"nameCompany" : {
".validate": "newData.isString() && newData.val().length < 100"
},
"emailCompany" :{
".validate": "newData.isString() && newData.val().length < 100"
}
}
}
}
}
In your intFirebase function you are only calling your database if there is a current user already logged in. The reason your email is working, is only because you are using 'user.email,' after it sees that a user is indeed logged in.
If you are trying to create a new user (which I think that is what your event listener at the top is trying to do), then you should move your add function to fire off when you submit the form.
I have an object array of users, which each object has 'username' and 'password'.
There is then a login page, where once the user enters in a username and a password, I want to pass that into the reducer and compare them with each object in the 'users' array, and if an object that matches both, 'password' and 'username', is found, I want it return 'true'.
Following is the reducer:
const usersReducer = function(users = [], action){
switch (action.type){
case 'VERIFY_USER':
return users.map((user)=> {
if(user.username === action.username && user.password === action.password){
return true
} else{
return false
}
})
}
default:
return users
}
}
But it seems to return true all the time. Am I using map correct? If not, is there such a method where it'll go through each object in an array? Any insight or guidance would be appreciated. Thank you in advance!
EDIT**
Calling it from the following:
verifyLoginUser(){
event.preventDefault()
if(this.props.actions.verifyUser(this.props.loginUser.username, this.props.loginUser.password)){
console.log('LOGGED IN')
} else {
console.log('NOT LOGGED IN')
}
}
With the following reducer:
case 'VERIFY_USER':
let isVerified = false;
users.forEach((user)=> {
if(user.username === action.username && user.password === action.password){
isVerified = true;
return false;
}
});
return isVerified;
Use Array.some
return users.some(user => user.username === action.username && user.password === action.password);
Map function would return you an array. I suggest using a different native array function: 'find'. To check if user object exists in the array of users, you can do
function findUser(user) {
return (user.username === action.username && user.password === action.password);
}
var isUser = users.find(findUser) ? true : false;
return isUser;
use a boolean variable and forEach to accomplish what you want
case 'VERIFY_USER':
let isVerified = false;
users.forEach((user)=> {
if(user.username === action.username && user.password === action.password){
isVerified = true;
return false;
}
});
return isVerified;
to take this a step further lets say you wanted to iterate on this and return the correct user so that way you can populate a currentUser with it or something.
case 'VERIFY_USER':
let currentUser = null;
users.forEach((user)=> {
if(user.username === action.username && user.password === action.password){
currentUser = user;
return false;
}
});
return currentUser;
EDIT: to what we were talking about in the comments
lets say you make a request to login a user somewhere. and the function lives on your props
this.props.loginUser({my params here});
now your actual action.
loginUser = (data) => {
// whatever method you are using to make the request goes here.
someRequestMethod('/login/, data).then( (response) => {
if(response.status === 200){
dispatch(type: USER_LOGIN, payload: response.data); // whatever the user is that comes back from the response. I just put data for an example
}
})
}
now in your reducer
const populateState = (user) => {
return {
id: user.id,
username: user.username,
email: user.email,
isAuthenticated: Object.keys(user).length > 0
};
}
let defaultState = {id: null, username: '', email: '', isAuthenticated: false};
const loginReducer = (currentUser = defaultState) => {
switch (action.type){
case 'USER_LOGIN':
return Object.assign({}, currentUser, populateState(action.payload));
return currentUser;
}
finally, everywhere else you just look for the current user.
if(this.props.currentUser.isAuthenticated){
// do stuff
}
I'm having quite a hard time understanding how to chain promises. I'm writing login function for my app, leverating Loopback's Angular SDK. The objective, upon validating a user's credentials, is to confirm that the user's account is active, then fetch some additional properties including the user's role and set a flag to true if the user has admin privileges.
Here's my code...
$scope.login = function (user) {
User.login(user).$promise.then(
function (data) {
$rootScope.activeUser = data;
$rootScope.user_id = $rootScope.activeUser.user.username;
console.log('Active User: ', $rootScope.activeUser.user.email);
console.log('Status: ', $rootScope.activeUser.user.status);
if ($rootScope.activeUser.user.status === 'Y') {
$scope.loginError = false;
function checkAdmin(eid) {
Se_user.findById({
id: eid
}).$promise.then(
function (data1) {
var user_properties = data1;
if (user_properties.role === 'Admin') {
$rootScope.isAdmin = true;
console.log('isAdminInside: ', $rootScope.isAdmin);
return true;
} else {
//$rootScope.isAdmin = false;
return false;
}
});
};
var isAdmin = checkAdmin($rootScope.user_id);
console.log('isAdminOutside: ', $rootScope.isAdmin);
$state.go('home');
} else {
$scope.loginError = true;
$scope.loginErrorMessage = "Your account has been disabled. Please contact BMT Support for assistance";
}
},
function (err) {
console.log('Error: ', err)
$scope.loginError = true;
$scope.loginErrorMessage = "You've entered an invalid User ID or Password. Please try again.";
});
};
I've been troubleshooting by writing to the console, here's a sample of the output...
Active User: user#email.com
Status: Y
isAdminOutside: undefined
isAdminInside: true
How should I restructure so that the result of checkAdmin is properly returned after a successful login of an active user?
Try changing this part of code :
function checkAdmin(eid) {
return Se_user.findById({
id: eid
}).$promise.then(
function(data1) {
var user_properties = data1;
if (user_properties.role === 'Admin') {
$rootScope.isAdmin = true;
console.log('isAdminInside: ', $rootScope.isAdmin);
return true;
} else {
//$rootScope.isAdmin = false;
return false;
}
});
};
var isAdmin = checkAdmin($rootScope.user_id)
.then(function(val) {
console.log('isAdminOutside: ', val);
$state.go('home');
});
I'm very confusing because of 'this' property.
What does "delete this.user;" mean in AuthenticationFactory. I think function "check" is a method so it will be bind with 'auth' object. But, there is no 'user' property in 'auth' Object. Can you explain it?
Also, in 'UserAuthFactory' (delete AuthenticationFactory.user, delete AuthenticationFactory.userRole)
I can't figure out what are "user" and "userRole" properties. There are no such properties in AuthenticationFactory.
Here the my code from http://thejackalofjavascript.com/architecting-a-restful-node-js-app/
myApp.factory('AuthenticationFactory', function($window) {
var auth = {
isLogged: false,
check: function() {
if ($window.sessionStorage.token && $window.sessionStorage.user) {
this.isLogged = true;
} else {
this.isLogged = false;
delete this.user;
}
}
}
return auth;
});
myApp.factory('UserAuthFactory', function($window, $location, $http, AuthenticationFactory) {
return {
login: function(username, password) {
return $http.post('http://localhost:3000/login', {
username: username,
password: password
});
},
logout: function() {
if (AuthenticationFactory.isLogged) {
AuthenticationFactory.isLogged = false;
delete AuthenticationFactory.user;
delete AuthenticationFactory.userRole;
delete $window.sessionStorage.token;
delete $window.sessionStorage.user;
delete $window.sessionStorage.userRole;
$location.path("/login");
}
}
}
});
If you look further down, to the controller code:
$scope.login = function() {
var username = $scope.user.username,
password = $scope.user.password;
if (username !== undefined && password !== undefined) {
UserAuthFactory.login(username, password).success(function(data) {
AuthenticationFactory.isLogged = true;
AuthenticationFactory.user = data.user.username;
AuthenticationFactory.userRole = data.user.role;
$window.sessionStorage.token = data.token;
$window.sessionStorage.user = data.user.username; // to fetch the user details on refresh
$window.sessionStorage.userRole = data.user.role; // to fetch the user details on refresh
$location.path("/");
}).error(function(status) {
alert('Oops something went wrong!');
});
} else {
alert('Invalid credentials');
}
};
On a successfully login, the controller is adding the properties user and userRole to the AuthenticationFactory.