At the moment I have javascript that allows all users from the (_User) table to log in. I have set up a Role called (Admins) within the role table and assigned one user to this role. Would this be an if statement?
At the moment this is how the user logs in successfully
$scope.logIn = function(form) {
Parse.User.logIn(form.username, form.password, {
success: function(user) {
$scope.currentUser = user;
$scope.$apply();
window.location.href = "TEST.html";
},
It's easy to check whether any user belongs to a role. The only tricky part is to realize that the check includes a query, and is therefore an asynchronous operation. So first, a general purpose role checking function:
function userHasRole(user, roleName) {
var query = new Parse.Query(Parse.Role);
query.equalTo("name", roleName);
query.equalTo("users", user);
return query.find().then(function(roles) {
return roles.length > 0;
});
}
This returns a promise that will be fulfilled with a boolean, so you can call it like this:
var currentUser = Parse.User.current();
// is the user an "admin"?
userHasRole(currentUser, "admin").then(function(isAdmin) {
console.log((isAdmin)? "user is admin" : "user is not admin");
});
Apply it like this in your code. In the view:
<form role="form" name="loginForm">
<div class="form-group">
<label>Email</label>
<input type="email" class="form-control" name="email" ng-model="user.username" />
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password" ng-model="user.password" />
</div>
<div class="form-group">
<button class="btn btn-ar btn-primary" ng-click="pressedLogIn()">Log in</button>
</div>
</form>
And in the controller:
(function() {
'use strict';
angular.module('myApp.controllers').controller('LogInController', LogInController);
LogInController.$inject = ['$scope'];
function LogInController($scope) {
$scope.user = { username:"", password:""};
function userHasRole(user, roleName) {
// defined exactly as above
// my real app has a user service, and this would be better placed there
}
$scope.pressedLogIn = function() {
if ($scope.loginForm.$valid) {
Parse.User.logIn($scope.user.username, $scope.user.password).then(function(user) {
$scope.user = user;
return userHasRole(user, "administrator");
}).then(function(isAdmin) {
alert("user is admin = " + isAdmin);
}, function(e) {
alert(error.message);
});
}
};
}
})();
Related
I am creating a Cognito user from the AWS Console. I am asked to change the password at first login. I want to prompt up a new page or hide a div in the login page to allow the user to pass the new password . Could you please help me how to prompt the new password page with the below code
login.tml
<div class="login">
<div>
<form class="login-form"
[formGroup]="loginForm"
(ngSubmit)="onLogin()" >
<div >
<div fxFlexFill>
<mat-form-field >
<input
type="email"
matInput
placeholder="Your email"
formControlName="email">
<mat-error>Invalid or missing email.</mat-error>
</mat-form-field>
</div>
</div>
<div >
<div >
<mat-form-field >
<input
type="password"
matInput
placeholder="password"
formControlName="password">
<mat-error>Missing password.</mat-error>
</mat-form-field>
</div>
</div>
Login.ts
export class Login implements OnInit {
constructor(private example:ExampleService,
private _router: Router) {
}
onLogin() {
const email=this.loginForm.get('email').value
const password=this.loginForm.get('password').value
this.example.LogIn(email, password).subscribe((data) => {
this._router.navigate(['/home']);
}, (err)=> {
});
}
ExampleService.ts
LogIn(email, password) {
return Observable.create(observ => {
cognitoUser.authenticateUser(authenticationDetails, {
newPasswordRequired: function(userAttributes, requiredAttributes) {
//How do I prompt a new password page from here and collect the form
value
and pass the value on below password paramaters
const email1={
email:email
};
cognitoUser.completeNewPasswordChallenge(password, email1, this)
},
onSuccess: function (result) {
observ.next(result);
observ.complete();
},
onFailure: function(err) {
console.log(err);
observ.error(err);
},
});
});
}
don't know how do I verify the user is a first time user or not. If It is a first-time user how do I show a new page within a call back function(newPasswordRequired: function()).
I have created an application managing contacts. The user can add a contact. After filling the name, I would like to check if the value already exists in the DB.
Can you please help for doing that?
I have created a new field username and I created a directive but I don't know if this way is the best solution. The query is correctly executed. But I improve some difficulties for displaying the results "username exists already" (during the loading it's correctly displayed "checking.....").
Here the file app.js (with the module and the controler "ctrlContacts"):
var app=angular.module('ContactsApp', ['ngRoute', 'ui.bootstrap', 'ngDialog']);
// register the interceptor as a service
app.factory('HttpInterceptor', ['$q', '$rootScope', function($q, $rootScope) {
return {
// On request success
request : function(config) {
// Return the config or wrap it in a promise if blank.
return config || $q.when(config);
},
// On request failure
requestError : function(rejection) {
//console.log(rejection); // Contains the data about the error on the request.
// Return the promise rejection.
return $q.reject(rejection);
},
// On response success
response : function(response) {
//console.log(response); // Contains the data from the response.
// Return the response or promise.
return response || $q.when(response);
},
// On response failure
responseError : function(rejection) {
//console.log(rejection); // Contains the data about the error.
//Check whether the intercept param is set in the config array.
//If the intercept param is missing or set to true, we display a modal containing the error
if (typeof rejection.config.intercept === 'undefined' || rejection.config.intercept)
{
//emitting an event to draw a modal using angular bootstrap
$rootScope.$emit('errorModal', rejection.data);
}
// Return the promise rejection.
return $q.reject(rejection);
}
};
}]);
// MY DIRECTIVE FOR CHECKING IF THE USERNAME IS ALREADY USED
app.directive('usernameAvailable', function($timeout, $q, $http, ContactService) {
return {
restrict: 'AE',
require: 'ngModel',
link: function(scope, elm, attr, ngModel) {
ngModel.$asyncValidators.usernameExists = function() {
return ContactService.searchContactByName('ADAM').success(function(contact){
$timeout(function(){
ngModel.$setValidity('usernameExists', contact);
ngModel.$setValidity('unique', false);
scope.contacts = contact;
alert(contact.length);
}, 1000);
});
};
}
}
});
app.controller('ctrlAddContacts', function ($scope, ContactService){
$scope.title="Add a contact";
ContactService.getCountry().success(function(countries){
$scope.countries = countries;
});
ContactService.loadCategory('undefined',0).success(function(categories){
$scope.categories = categories;
});
$scope.Category = function (contactType) {
if (contactType){
ContactService.loadCategory(contactType,0).success(function(categories){
$scope.categories = categories;
});
}
}
$scope.submitForm = function(contact){
if($scope.ContactForm.$valid){
ContactService.addNewPerson(contact).success(function(Person){
$scope.ContactForm.$setPristine();
$scope.contact= Person;
var personID = Person[0]["ID"];
window.location="#/view-contacts/" + personID;
});
}
}
});
the file for the factories: "appServices.js":
app.factory('ContactService', function($http){
var factory={};
factory.searchContactByName=function(string){
if (string){
chaine='http://myapp/contacts.cfc?method=searchContactByName&contactName=' + string;
}else{
chaine='';
}
//alert(chaine);
return $http.get(chaine);
};
return factory;
})
the file for my view "manageContact.html":
<h3>{{title}}</h3>
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">Person Sheet</div>
</div>
<div class="panel-body">
<form name="ContactForm" class="form-horizontal" role="form" novalidate ng-submit="submitForm(contact)">
<!--------------------- USERNAME FIELD AND CHECK IF IT EXISTS ------------------START-->
<div>
<input type="text"
name="username"
ng-model="username"
username-available
required
ng-model-options="{ updateOn: 'blur' }">
<div ng-if="ContactForm.$pending.usernameExists">checking....</div>
<div ng-if="ContactForm.$error.usernameExists">username exists already</div>
</div>
<!---------------------- USERNAME FIELD AND CHECK IF IT EXISTS --------------------END-->
<div class="form-group">
<label for="txtLastName" class="col-sm-2 control-label">Last Name *</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="txtLastName" maxlength="100" placeholder="Enter Last Name" required ng-model="contact.LASTNAME">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" class="btn btn-primary" value="Submit" ng-disabled="ContactForm.$invalid">
Cancel
</div>
</div>
</form>
</div>
</div>
Thank you in advance for your help.
Regards,
it should be
<div ng-if="ContactForm.$pending.usernameExists">checking....</div>
<div ng-if="ContactForm.username.$error.unique">username exists already</div>
Use ng-show and ng-hide instead of ng-if
<div ng-show="ContactForm.$pending.usernameExists">checking....</div>
<div ng-show="ContactForm.$error.usernameExists">username exists already</div>
I've this problem, when I click on login button, the chrome console log this:
angular.min.js:117 TypeError: Cannot read property 'then' of undefined
at m.$scope.logIn (loginModuleController.js:11)
Service:
angular.module('loginModule')
.factory('loginService', function($http){
return{
login: function(username, password){
var session;
$http.post('../server/php/auth/auth.php', {
username: username,
password: password
})
.then(function(res){
session = res;
});
return session;
},
isLogged: function(){
return $http.get('../angCMS/server/php/auth.php?is_logged=true');
},
logOut: function(){
return $http.get('../angCMS/server/php/auth.php?logout=true');
}
};
});
controller:
angular.module('loginModule')
.controller('LoginCtrl', ['$scope', 'loginService', function($scope, loginService){
$scope.auth = false;
$scope.username;
$scope.password;
$scope.logIn = function(){
loginService.login($scope.username, $scope.password).then(function(response){
}, function(res){
});
};
$scope.isLogged = function(){
loginService.isLogged()
.then(function(response){
if(response){
$scope.auth = true;
}
});
};
$scope.logOut = function(){
loginService.logOut()
.then(function(response){
if(response){
$scope.auth = false;
}
});
};
}]);
and this is the html template:
<div class="container" ng-if="auth==false">
<div class="col-md-4 col-md-offset-4">
<div class="row">
<br/><h2 align="center">Login</h2>
</div>
<div class="well">
<form class="form-horizontal">
<fieldset>
<div class="form-group">
<input type="text" class="form-control" placeholder="Username" ng-model="username" required>
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Password" ng-model="password" required>
</div>
<div class="form-group">
<button class="btn btn-md btn-primary btn-block" type="submit" ng-click="logIn()">Sign in</button>
</div>
</fieldset>
</div>
</form>
</div>
</div>
PHP login method:
public function login($user, $pass){
$user = htmlspecialchars(trim($user));
$pass = md5(htmlspecialchars(trim($pass)));
$res = $this->DB->prepare("SELECT * FROM `admin` WHERE username = :user");
if(!$res->execute(Array(":user"=>$user)))
die(mysql_error());
$row = $res->fetch(PDO::FETCH_ASSOC);
if(!$row['password'] == $pass)
die("Errore: password errata!");
$_SESSION['logged'] = $row;
array_push($session, $_SESSION['logged'], true);
return $session;
}
This is more of a misuse of promises issue.
You might want to first take a look of how promises work:
https://docs.angularjs.org/api/ng/service/$q
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
From your service code:
login: function(username, password){
var session;
$http.post('../server/php/auth/auth.php', {
username: username,
password: password
})
.then(function(res){
session = res;
});
return session;
}
When login(username, password) is called, session is still undefined upon returning.
This is because $http.post() is an asynchronous function, the .then() clause does not get executed immediately.
As pointed out by Snixtor's answer,
you should "return the return value of $http.post()":
login: function(username, password){
return $http.post('../server/php/auth/auth.php', {
username: username,
password: password
});
}
Then referring to your controller's logIn method:
$scope.logIn = function(){
loginService.login($scope.username, $scope.password).then(function(response){
// response === 'session'
}, function(res){
});
};
the response parameter from loginService.login().then() is exactly the value of your intended session variable from your previous implementation.
You're returning an unassigned variable named "session". So what you are doing here in your logged in method is returning undefined. Undefined does not have a method called then.
login: function(username, password){
var session;
$http.post('../server/php/auth/auth.php', {
username: username,
password: password
})
.then(function(res){
session = res;
});
return session;
},
My guess is you actually want to return the $http.post method, which in turn returns a promise. That way you can use the session in the controller?
Your service function login is failing to return the promise created by the call to $http.post. Instead, you need this:
login: function(username, password){
return $http.post('../server/php/auth/auth.php', {
username: username,
password: password
});
}
Note too that I've removed the session variable from the function. It's the then function in your controller that needs to be dealing with the response.
Your isLogged and logOut functions look good already. Just repeat that pattern.
I am very much new in AngularJS and I have the following problem:
View:
<div>
<form role="form" name="loginForm" class="form-horizontal login-form">
<div class="form-group">
<p class="login-form-msg">Welcome : {{user.username}}</p>
<label for="inputUserName" class="col-sm-2 control-label login-form-label">Base</label>
<div class="col-sm-10">
<input type="text" placeholder="Enter base" class="form-control" required ng-model="user.code">
</div>
</div>
<div class="form-group">
<label for="inputUserName" class="col-sm-2 control-label login-form-label">Username</label>
<div class="col-sm-10">
<input type="text" placeholder="Enter name" class="form-control" required ng-model="user.username">
</div>
</div>
<div class="form-group">
<label for="inputPassword" class="col-sm-2 control-label login-form-label">Password</label>
<div class="col-sm-10">
<input type="password" placeholder="Password" id="inputPassword" class="form-control" required ng-model="user.password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10 login-form-button">
<button class="btn btn-default" type="submit" ng-disabled="loginForm.$invalid" ng-click="login(user)">Sign in</button>
</div>
<p class="login-form-msg">{{msgtxt}}</p>
</div>
</form>
</div>
Main js:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/login', {
templateUrl: 'partials/login.html',
controller:'loginCtrl'
});
$routeProvider.when('/welcome', {
templateUrl: 'partials/welcome.html',
controller:'loginCtrl'
});
$routeProvider.otherwise({ redirectTo: '/login' });
}]);
I have the following factory:
myApp.factory('getURLService', function ($http, config) {
return {
getURL: function (user,scope) {
$http.get(config.backend + "/Device/GetURLbyCode", {
params: { code: user.code }
})
.success(function (data) {
var url = '';
if (data.status == 'succ') {
url = data.Result;
}
else {
scope.msgtxt = data.msg;
}
return url;
});
}
}
});
I need to use the returned value from this factory in other factories.
For example in my login factory:
myApp.factory('loginService', function ($http, $location, config) {
return {
login: function (user,url,scope) {
$http.get(url + "/Device/Register", {
params: { userName: user.username, password: user.password }
})
.success(function (data) {
if (data.status == 'succ') {
$location.path('/welcome');
}
else {
scope.msgtxt = data.msg;
}
});
}
}
});
This is my controller:
myApp.controller('loginCtrl', function ($scope, getURLService, loginService) {
$scope.msgtxt = '';
$scope.login = function (user) {
loginService.login(user,url,$scope); //call login service
}
});
What do I need to do in my controller to actually return the url and then send it to the login service or any other service (or even controller) in the future?
Thanks in advance for your time and suggestion.
For returning data from the function you should return promise object which $http.get already returns it.
Additional thing which I wanted to point out is, passing $scope to the service disobey the rule of singleton, as you are creating a service which is dependent of the controller scope. Service should only accept the parameter and return the result by processing it, nothing else.
Code
return {
getURL: function (user,scope) {
return $http.get(config.backend + "/Device/GetURLbyCode", {
params: { code: user.code }
})
.then(function (res) {
var data = res.data;
var url = '';
if (data.status == 'succ') {
url = data.Result;
}
else {
scope.msgtxt = data.msg;
}
return url;
});
}
}
LoginService
myApp.factory('loginService', function ($http, $location, config) {
return {
login: function (user,url) {
return $http.get(url + "/Device/Register", {
params: { userName: user.username, password: user.password }
})
.then(function (response) {
var data = response.data;
if (data.status == 'succ') {
$location.path('/welcome');
return;
}
return data.msg;
});
}
}
});
Controller
getURLService.getURL(user).then(function(url){
//assuming you already having value of user available here
loginService.login(user,url).then(function(message){ //call login service
if(message)
$scope.msgtxt = message;
});
});
I'm trying to add a signup function, using a controller and a factory, to my Angular app, but I haven't been able to get several strings (tied conditionally to success or failure) to return from my factory to my controller.
The return statements below only return empty strings at first (I assume this has to do with the asynchronous http, but am not sure). In any case, how would I return the two strings I desire (_alertType and _alertMessage) with the updated values from .success or .error?
signup.html
<div class="col-md-6 container-fluid">
<div class="jumbotron text-center" ng-controller="SignupController as vm">
<p class="lead">
<h2>Account Creation</h2>
Welcome! Please make an account
</p>
<form ng-submit="vm.signup()">
<p><input type="text" name="username" value="" placeholder="Username or Email" ng-model="username"></p>
<p><input type="password" name="password" value="" placeholder="Password" ng-model="password"></p>
<p class="submit"><input type="submit" name="commit" value="Sign Up"></p>
<alert ng-show="vm.alertMessage" type="{{ vm.alertType }}">{{ vm.alertMessage }}</alert>
</form>
</div>
</div>
signup.factory.js
(function() {
angular
.module('app')
.factory('signupFactory', signupFactory);
signupFactory.$inject = ['$http'];
function signupFactory($http) {
var _alertType = '';
var _alertMessage = '';
var service = {
signup: signup,
getAlertType: getAlertType,
getAlertMessage: getAlertMessage
};
return service;
function signup(username, password) {
var request = $http({
method: 'POST',
url: 'http://localhost:8080/user',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: {
username: username,
password: password
}
});
request.success(function(){
_alertType = "success";
_alertMessage = "Signed Up";
});
request.error(function(){
_alertType = "danger";
_alertMessage = "Signup Failed";
});
}
function getAlertType() {
return _alertType;
}
function getAlertMessage() {
return _alertMessage;
}
}
})();
signup.controller.js
(function() {
'use strict';
angular
.module('app')
.controller('SignupController', SignupController);
SignupController.$inject = ['$scope', 'signupFactory'];
function SignupController($scope, signupFactory) {
var vm = this;
vm.signup = function() {
signupFactory.signup($scope.username, $scope.password);
vm.alertMessage = signupFactory.getAlertMessage();
vm.alertType = signupFactory.getAlertType();
}
}
})();
You should look for promises
var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
alert('Success: ' + greeting);
}, function(reason) {
alert('Failed: ' + reason);
});