I want to handle the inactive users and keep them out as long as they are not active. Currently, I am just alerting them that they are not active and letting them log in. However, I just want to throw in a login error and keep them out as long as they are not active. By "active" I mean, they haven't activated the email token.
'use strict';
angular.module('myapp').controller('LoginCtrl', function ($scope, alert, auth, $state, $auth, $timeout) {
$scope.submit = function () {
$auth.login({
email: $scope.email,
password: $scope.password
})
.then(function(res) {
var message = 'Thanks for coming back ' + res.data.user.email + '!';
if (!res.data.user.active)
message = 'Just a reminder, please activate your account soon :)';
alert('success', 'Welcome', message);
return null;
})
.then(function() {
$timeout(function() {
$state.go('main');
});
})
.catch(handleError);
}
function handleError(err) {
alert('warning', 'oops there is a problem!', err.message);
}
});
You could always log them out immediately with $auth.logout().
Related
I just want to use load bar in my app. I got service in angularjs like this
app.service('gethostsbyip', [ '$http', '$q', function($http, $q){
this.gethostsbyip = function(hostname, username, password){
var deffered = $q.defer();
var result = $http.post(REST_API_IP + 'discover?ip=' + hostname + '&username=' + username + '&password=' + password).then(function(resp){
deffered.resolve(result);
location.href="#createvirtualization";
toastr.success('Your hosts, templates, networks have been updated!', 'Data was loaded!');
}).catch(function(e){
toastr.error('Some data in your form is incorrect. Please, try again!', 'Error!');
});
return deffered.promise;
};
}]);
And in the angular controller, I need to change flag into false value after my service (gethostsbyip.gethostsbyip) is done.
When the function runs without errors the flag changes, but I need to change the flag in case of an error in the service.
app.controller('discoverCtrl', ['$scope', '$q', function($scope, $q) {
$scope.submitButt = function(hostname, username, password){
if(!hostname || !username || !password){
}
else {
$scope.flag = true;
gethostsbyip.gethostsbyip(hostname, username, password).then(function(res){
$scope.test = false;
})
.catch(function(e){
$scope.test = false;
})
}
};
}
then event accepts two parameter.
app.controller('discoverCtrl', ['$scope', '$q', function($scope, $q) {
$scope.submitButt = function(hostname, username, password){
if(!hostname || !username || !password){
}
else {
$scope.flag = true;
gethostsbyip.gethostsbyip(hostname, username, password)
.then(
// you currently have one callback in your `then` method
function(res){
$scope.test = false;
}
// solution
, function(resForErrorCase){
$scope.test = false;
})
.catch(function(e){
$scope.test = false;
})
}
};
Promise definition reference
Reject the promise if error occurs
.catch(function(e) {
deffered.reject(e);
toastr.error('Some data in your form is incorrect. Please, try again!', 'Error!');
});
I am new using Angularjs and I'm building a login-page using AngularJS through REST API. I'm facing an issue when I am trying to submit my form. I browsed through so many web-site and links, but I din't got proper answer. Please don't tell me to google it, because I already have so many blue links. If you know anything , please correct me and if you have any working example share it .
AngularJS :
var app = angular.module('logapp',['toastr','ngRoute']);
app.factory('Auth', function($http){
var service = {};
service.login = function(username,password) {
$http.post('http://localhost:3000/loginfo',
{
username : username,
password : password
})
.then(
function successCallback(response){
console.log(response.data);
});
};
service.isAuthenticated = function() {
return {
isAuthenticated : false,
}
};
return service;
});
app.controller('credientials', function($scope,$http,Auth) {
$scope.isAuthenticated = false;
$scope.userCred = {
username: '',
password: ''
}
/*-----Form Submition-----*/
$scope.log = function(userCred){
Auth.login(userCred, function(result) {
console.log(Auth);
if (result === true) {
console.log('success');
} else {
$scope.Error = response.message;
}
});
};
First things first, this part
Auth.login(userCred, function(result) {
is Wrong. Your service.login takes 2 parameters. And they are username and password. It does not take any callback.
Right way to do it is like this
Auth.login(userCred.username, userCred.password)
.then(function(result){
console.log(result);
})
.catch(function(err){
console.error(err);
});
Which goes without saying, you refactor your service.login as follows
service.login = function(username,password) {
return $http.post('http://localhost:3000/loginfo',{
username : username,
password : password
})
}
Currently, when the users logs in, the login page does't redirect to the homepage.
'use strict';
angular.module('myapp').service('auth', function auth($http, API_URL, authToken, $state, $window, $q) {
function authSuccessful(res) {
authToken.setToken(res.token);
$state.go('main');
}
this.login = function (email, password) {
return $http.post(API_URL + 'login', {
email: email,
password: password
}).success(authSuccessful);
}
this.register = function (email, password) {
return $http.post(API_URL + 'register', {
email: email,
password: password
}).success(authSuccessful);
}
However, I have set my $state.go to redirect to main. Where is the problem? why is it not redirecting?
annex
here is my login.js controller, how it looks:
angular.module('myapp').controller('LoginCtrl', function ($scope, alert, auth, $auth) {
$scope.submit = function () {
$auth.login({
email: $scope.email,
password: $scope.password
})
.then(function(res) {
var message = 'Thanks for coming back ' + res.data.user.email + '!';
if (!res.data.user.active)
message = 'Just a reminder, please activate your account soon :)';
alert('success', 'Welcome', message);
})
.catch(handleError);
}
// i forgot to include this error handler in my code:
function handleError(err) {
alert('warning', 'oops there is a problem!', err.message);
}
});
Since this is an async action, angular doesn't know when the action finishes and thus when to update the $scope. For this to work you'll need to manually call $scope.apply(), but since you don't have access to the $scope in your service, you need to move the redirection logic (i.e. $state.go('main')) inside a controller, and call it like this:
angular.module('myapp').controller('LoginCtrl', function($scope, auth, $state) {
function redirect(res) {
$state.go('main');
// manually update the scope
$scope.$apply();
}
auth.login(email, password)
.success(redirect);
});
EDIT: Integrate with the given controller
angular.module('myapp').controller('LoginCtrl', function ($scope, alert, auth, $auth) {
$scope.submit = function () {
$auth.login({
email: $scope.email,
password: $scope.password
})
.then(function(res) {
var message = 'Thanks for coming back ' + res.data.user.email + '!';
if (!res.data.user.active) {
message = 'Just a reminder, please activate your account soon :)';
}
alert('success', 'Welcome', message);
return null;
})
.then(function() {
$state.go('main');
// manually update the scope
$scope.$apply();
})
// google replacement of the above commented out code bit
.catch(handleError);
}
});
EDIT 2: Use $timeout instead of $scope.$apply so you don't get $digest error.
angular.module('myapp').controller('LoginCtrl', function ($scope, alert, auth, $auth, $timeout) {
...
.then(function() {
// $timeout calls $scope.$apply() by default,
// but it does it in a safely manner - never throws a '$digest already in progress' exception
$timeout(function() {
$state.go('main');
});
})
...
My logout function, linked to a logout button is:
$scope.logoutUser = function() {
var ref = new Firebase("https://buzzmovieionic.firebaseio.com");
ref.unauth();
console.log(ref.getAuth);
$state.transitionTo('login');
}
When I click logout, it prints this to the console:
function (){x("Firebase.getAuth",0,0,arguments.length);return this.k.P.we()}
I am checking for authData in my other controller with:
CONTROLLER:
.controller('SearchCtrl',
function ($scope, $http, Movie, $state, UsersRef, AuthData, $timeout) {
$scope.$on('$ionicView.enter', function () {
if (!AuthData) {
console.log("Auth data null!");
swal("Unauthorized", "You are not logged in", "error");
$state.transitionTo('login');
} else {
console.log("Auth data found: " + AuthData);
//do stuff
}
});
})
FACTORY:
.factory("AuthData", [
function () {
var ref = new Firebase("https://buzzmovieionic.firebaseio.com");
var data = null;
ref.onAuth(function (authData) {
if (authData) {
data = authData;
}
});
return data;
}
])
If I logout, then go back to the page linked to SearchCtrl by changing the URL, it still says it found the authData.
However, if I try and go to the search page the FIRST time I open the app, before anybody has logged in, it gives me the right error message and exits out to the login page.
How can I ensure the user can't go back into the app after logging out?
Welcome to async programming 101.
Firebase's onAuth methods listens for changes on auth state. When the auth state changes, the callback method you provide is invoked. But while it's waiting for auth state changes, your other code continues to run.
It most easy to see this if you add some log statements to your code:
.factory("AuthData", [
function () {
var ref = new Firebase("https://buzzmovieionic.firebaseio.com");
var data = null;
console.log('before onAuth');
ref.onAuth(function (authData) {
console.log('in callback');
if (authData) {
data = authData;
}
});
console.log('after onAuth');
return data;
}
])
The output is going to be:
before onAuth
after onAuth
in callback
Which is likely not what you expected when you wrote this code.
The simplest way to fix this in your code is to use the synchronous ref.getAuth() method:
.factory("AuthData", [
function () {
var ref = new Firebase("https://buzzmovieionic.firebaseio.com");
return ref.getAuth();
}
])
But you're going to run into this asynchronicity problem quite often. I highly recommend using and studying AngularFire instead of reinventing the wheel.
You are never cleaning data inside AuthData so it will always have data after the first guy logs in. I'm not familiar with Firebase but you need something like this in your AuthData factory:
.factory("AuthData", [
function () {
var ref = new Firebase("https://buzzmovieionic.firebaseio.com");
var data = null;
ref.onAuth(function (authData) {
if (authData) {
data = authData;
}
else
data = null;
});
return data;
}
])
I have LoginController and securityService.
This is LoginCtrl
// place the message if something goes wrong
$scope.authMsg = '';
$scope.login = function () {
$scope.authMsg = '';
var loginData = {email: $scope.account.email, password: $scope.account.password};
securityService.login(loginData);
};
This is securityService
login: function (logData) {
var _vm = this;
$http
.post('/api-token-auth/', logData)
.then(function (response) {
// assumes if ok, response is an object with some data, if not, a string with error
// customize according to your api
if (!response.data.token) {
_vm.authMsg = 'Incorrect credentials.';
} else {
$cookieStore.put('djangotoken', response.data.token);
$http.defaults.headers.common.Authorization = 'JWT ' + response.data.token;
$http.get('/api/account/restricted/').then(function (response) {
authService.loginConfirmed();
_vm.currentUser = response.data;
$rootScope.currentUser = response.data;
});
}
}, function (x) {
_vm.authMsg = 'Server Request Error';
});
},
This login is working fine but my problem is i don't know how can get the authMesg from service to controller because that is async. Everytime i get blank message in case of invalid login
you need to use promise service of angular to make you controller and service syn
login: function (logData) {
var _vm = this,d= $$q.defer();
$http
.post('/api-token-auth/', logData)
.then(function (response) {
// assumes if ok, response is an object with some data, if not, a string with error
// customize according to your api
if (!response.data.token) {
_vm.authMsg = 'Incorrect credentials.';
} else {
$cookieStore.put('djangotoken', response.data.token);
$http.defaults.headers.common.Authorization = 'JWT ' + response.data.token;
$http.get('/api/account/restricted/').then(function (response) {
authService.loginConfirmed();
_vm.currentUser = response.data;
$rootScope.currentUser = response.data;
});
}
d.resolve(vm.authMsg);
}, function (x) {
_vm.authMsg = 'Server Request Error';
d.reject(vm.authMsg);
});
},
In controller you need to resolve this promise
securityService.login(loginData).then(function(data){
consol.log(data); // get success data
},function(error){
consol.log(data); // get error message data
})
and inject $q in your service.
This will give you authMsg
securityService.login(loginData).authMsg
But follow #Vigneswaran Marimuthu comments, that is best practice.