Building $routeProvider based on Role - javascript

I have a very simple requirement.
I have 3 User Roles:
CATUSER
LICUSER
ALLUSER
I have the value of the User Role in the $rootScope.userRole variable.
I have the User Role already defined before the AngularJS application starts because AngularJS app is called from a PHP script and User Role is already defined in the PHP script.
Now, when the AngularJS app starts, according to the Role I want to have following Routes:
$rootScope.userRole == "CATUSER"
if ($rootScope.userRole == "CATUSER") {
$routeProvider
.when("/catheter", {
title: "Catheter Expiration Code Generator",
templateUrl: "app/catheter/catheter.html",
controller: "CatheterController",
controllerAs: "vm"
})
.when("/support", {
title: "Support",
templateUrl: "app/support/support.html",
controller: "SupportController",
controllerAs: "vm"
})
.otherwise({
redirectTo: "/catheter"
});
}
$rootScope.userRole == "LICUSER"
if ($rootScope.userRole == "LICUSER") {
$routeProvider
.when("/license", {
title: "License Generator",
templateUrl: "app/license/license.html",
controller: "LicenseController",
controllerAs: "vm"
})
.when("/support", {
title: "Support",
templateUrl: "app/support/support.html",
controller: "SupportController",
controllerAs: "vm"
})
.otherwise({
redirectTo: "/license"
});
}
$rootScope.userRole == "ALLUSER"
if ($rootScope.userRole == "LICUSER") {
$routeProvider
.when("/license", {
title: "License Generator",
templateUrl: "app/license/license.html",
controller: "LicenseController",
controllerAs: "vm"
})
.when("/catheter", {
title: "Catheter Expiration Code Generator",
templateUrl: "app/catheter/catheter.html",
controller: "CatheterController",
controllerAs: "vm"
})
.when("/support", {
title: "Support",
templateUrl: "app/support/support.html",
controller: "SupportController",
controllerAs: "vm"
})
.otherwise({
redirectTo: "/license"
});
}
I don't want to use UI Router.

I use UI Router for this kind of purpose in past.
Here is the sample code to get you started
angular
.module('app', [
])
.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('license', {
url: 'url',
templateUrl: './preview.html',
controller: 'LicenseController',
data: {
requiredAuth: true,
role: ['CATUSER', 'LICUSER'],
permission : ['read', 'write', 'etc etc']
}
})
$urlRouterProvider.otherwise(subdomain1 + 'error');
})
.run(['$rootScope', '$state', function ($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
// is authenticated
var isAuthenticationRequired = toState.data
&& toState.data.requiredAuth
&& !AuthService.isAuthenticated() //some service to check if user is authenticated (I use localstorage lookup here)
;
// is authorized
var isAuthorizationRequired = toState.data
&& (toState.data.role && AuthService.IsInRole(toState.data.role))
&& (toState.data.permission && AuthService.IsInPermission(toState.data.permission))
;
if (isAuthenticationRequired) {
event.preventDefault();
$state.go('auth.login');
}
else if (isAuthorizationRequired) {
event.preventDefault();
$state.go('auth.denied');
}
});
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams, error) {
cfpLoadingBar.complete();
});
$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
cfpLoadingBar.complete();
});
}]);
Here you see License route has property data. Its required authentication and it is authorized for LICUSER and CATUSER roles. You can also add more permission check here for example read, write etc. If user is authenticated and authorized the requested the requested state will load up else will redirect to login or denied request.

Related

Multiple url changes with $routeChangeStart

Hi all I having a hard time figuring this out and ran out of ideas. I have this website which I should restrict some urls if the user has no authentication. I reviewed some questions and found something similar to this. But it is not quite what I wanted it to be.
So I have some link which do not require user authentication but can access the url.
Other link which needs both, access and user authentication.
So this is my app.js looks
angular.module('efutures', [
'ngRoute',
'ngCookies',
'ui.bootstrap',
]).config(['$routeProvider', '$httpProvider', function ($routeProvider, $httpProvider) {
$routeProvider.when('/login', {
templateUrl: 'app/pages/login.html',
controller: 'LoginController',
access: {
allowAnonymous: true //no need auth
}
})
.when('/signup', {
templateUrl: 'app/pages/Signup.html',
controller: 'SignupController',
access: {
allowAnonymous: true //no need auth
}
})
.when('/enteremail', {
templateUrl: 'app/pages/reset pages/reenteremail.html',
controller: 'EmailController',
access: {
allowAnonymous: true //no need auth
}
})
.when('/password-reset', {
templateUrl: 'app/pages/reset pages/password.reset.html',
controller: 'ResetPwdController',
access: {
allowAnonymous: false //needs auth
}
})
.when('/dashboard', {
templateUrl: 'app/pages/dashboard.html',
controller: 'DashboardController',
access: {
allowAnonymous: false //needs auth
}
})
.when('/registration', {
templateUrl: 'app/pages/registration1.html',
controller: 'registationController'
access: {
allowAnonymous: false //needs auth
}
});
$routeProvider.otherwise({
redirectTo: '/login'
});
}]).run(run);
run.$inject = ['$rootScope', '$location', '$cookieStore', '$http'];
function run($rootScope, $location, $cookieStore, $http) {
$rootScope.hasauth = localStorage.getItem('hasauth');
$rootScope.username = localStorage.getItem('username');
$rootScope.$on('$routeChangeStart', function (event, next, current) {
//console.log($rootScope.hasauth);
//console.log(next.access.allowAnonymous);
if (next.access.allowAnonymous || $rootScope.hasauth === null) {
$location.path('/login');
}
else {
event.preventDefault();
}
});
}
So as above explains code, I have 3 pages which doesn't need authentication and can be allowed to access the urls. Also after Logged in I should restrict going back to those 3 pages but should access other remaining ones
the authentication is taken by the loacalStorage hasauth which returns true when logged in and null when not.
How do I approach this? Help is greatly appreciated.

How to check angularfire authentication status in app.js

I am following the angularfire tutorial to authenticate users.
Users are able to register, signin and even signout in the app.
When I try to use a resolve to check for $requireSignIn() for some routes(ui-route), it doesn't work.
Also, I want to do a check for user authentication status($onAuthStateChanged()) in my app.js where my modules are loaded. Then if there is a change in authentication, update authentication service( userAuth). I am using ng-show="authData" / ng-hide="authData to change html for logged in elements. But sometimes even after login, some of these elements are still showing as not logged in. I think this has something to do with the authentication update status.
If a user is logged in and the try to visit the login/signup page send them back to home page.
Here is my app.js
angular
.module('myApp', [
'ngAnimate',
'ngAria',
'ngCookies',
'ngResource',
'ui.router',
'ngMeta',
'firebase'
])
.run(["$rootScope", "$state", function($rootScope, $state) {
$rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
if (error === "AUTH_REQUIRED") {
$state.go("home");
}
});
}])
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
function( $stateProvider, $urlRouterProvider, $locationProvider, ngMetaProvider, $location, userAuth) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('/', {
url: '/',
templateUrl: 'views/main.html',
controller: 'MainCtrl',
meta: {
'title': 'Goaf | Your next great destination',
'description': 'This is the description shown in Google search results'
}
})
.state('home', {
url: '/home',
templateUrl: 'views/home.html',
controller: 'HomeCtrl',
meta: {
'title': 'Goaf | Your next great destination',
'description': 'This is the description shown in Google search results'
},
resolve: {
"currentAuth": ["userAuth", function(userAuth) {
return userAuth.$requireSignIn();
}]
}
})
}]);
Here is the controller for the home page where I want only logged in users:
angular.module('myApp')
.controller('HomeCtrl', ["currentAuth", function ($rootScope, $scope, $http, $interval, $location, userAuth, dataservice, currentAuth) {
$scope.authData = userAuth.isLoggedIn();
}]);
And here is my userAuth service file:
angular.module('myApp')
.service('userAuth', ["$firebaseAuth", function($firebaseAuth) {
var firebaseAuthObject = $firebaseAuth();
this.login = function(loginEmail, loginPassword){
return firebaseAuthObject.$signInWithEmailAndPassword(loginEmail, loginPassword);
};
this.isLoggedIn = function(){
return firebaseAuthObject.$getAuth();
};
this.signOutUser = function() {
firebaseAuthObject.$signOut();
console.log('logging out user!');
};
}
]);

Angular flickers when authenticating user

I need help eliminating a flicker with Angular. I am getting a flicker every time a new route is passed through. I have a login and logout button outside the ng-view which uses ng-if="authenticated". The problem is any time a menu item is clicked and a new view is displayed the logout or login button flickers. Is there a way to eliminate this? Below is the module, config and run function.
PS. I am very new to Angular. This was a script from a tutorial on using Angular, php and mysql for a login system.
var app = angular.module('myApp', ['ngRoute', 'ngAnimate', 'ui.bootstrap', 'toaster']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/login', {
title: 'Login',
templateUrl: 'views/login.html',
controller: 'authCtrl'
})
.when('/logout', {
title: 'Logout',
templateUrl: 'views/login.html',
controller: 'logoutCtrl'
})
.when('/signup', {
title: 'Signup',
templateUrl: 'views/signup.html',
controller: 'authCtrl'
})
.when('/dashboard', {
title: 'Dashboard',
templateUrl: 'views/dashboard.html',
controller: 'authCtrl'
})
.when('/posts', {
title: 'Posts',
templateUrl: 'views/posts.html',
controller: 'authCtrl'
})
.when('/stats', {
title: 'Stats',
templateUrl: 'views/stats.html',
controller: 'authCtrl'
})
.when('/ambas', {
title: 'Ambassadors',
templateUrl: 'views/ambassadors.html',
controller: 'authCtrl'
})
.when('/images', {
title: 'Images',
templateUrl: 'views/images.html',
controller: 'authCtrl'
})
.when('/', {
title: 'Login',
templateUrl: 'views/login.html',
controller: 'authCtrl'
})
.otherwise({
redirectTo: '/posts'
});
}])
.run(function ($rootScope, $location, Data) {
$rootScope.$on("$routeChangeStart", function (event, next, current) {
$rootScope.authenticated = false;
Data.get('session').then(function (results) {
if (results.uid) {
$rootScope.authenticated = true;
$rootScope.uid = results.uid;
$rootScope.name = results.name;
$rootScope.email = results.email;
} else {
var nextUrl = next.$$route.originalPath;
if (nextUrl == '/signup' || nextUrl == '/login') {
} else {
$location.path("/login");
}
}
});
});
});
You are setting the authenticated value to false on every route change start. So every time a user clicks to change the route you set it to false, and then a few moments later you set it to true if authentication is fine. That will cause a flicker.
So, remove the $rootScope.authenticated = false; from the $routeChangeStart callback.
$rootScope.$on("$routeChangeStart", function (event, next, current) {
//$rootScope.authenticated = false; <--- *remove this*
Data.get('session').then(function (results) {
...........

Sails app using angular-ui-router fails to load state based views

I'm attempting to use angular-ui-router to display templates, based on state. Currently, i'm not getting errors in the terminal. In the console, I see "Uncaught TypeError: Cannot read property 'isDefined' of undefined" and "uncaught TypeError: Cannot read property 'isDefined' of undefined". This makes me think I'm not instantiating modules properly. New to angularjs and hoping someone might be able to point me in the right direction. app.js
var app = angular.module('app', ['ui.bootstrap', 'ui.router', 'ngMessages', 'app-templates'])
.run(function($rootScope, $state, Auth) {
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
if (!Auth.authorize(toState.data.access)) {
event.preventDefault();
$state.go('anon.login');
}
});
});
And, routes.js.
angular.module('app')
.config(function($stateProvider, $urlRouterProvider, AccessLevels) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('anon', {
abstract: true,
template: '<ui-view/>',
data: {
access: AccessLevels.anon
}
})
.state('anon.index', {
url: '/',
templateUrl: 'index.html'
})
.state('anon.login', {
url: '/login',
template: 'auth/login.html',
controller: 'LoginController'
})
.state('anon.register', {
url: '/register',
templateUrl: 'auth/register.html',
controller: 'RegisterController'
});
$stateProvider
.state('user', {
abstract: true,
template: '<ui-view/>',
data: {
access: AccessLevels.user
}
})
.state('user.messages', {
url: '/messages',
template: 'user/messages.html',
controller: 'MessagesController'
});
});

AngularJs with ui.router how to set authenticate for its children

i'am using AngularJS with ui-router, this is my current app.js configuration.
'use strict';
angular.module('nodeserverApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
'ui.bootstrap',
'ui.router'
])
.config(function ($routeProvider, $locationProvider, $httpProvider , $stateProvider , $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'partials/user/main',
controller: 'MainCtrl'
})
.state('dashboard', {
url: '/user/dashboard',
templateUrl: 'partials/user/dashboard/main',
controller: 'UserDashboardDashboardCtrl',
authenticate: true
})
.state('dashboard.welcome', {
url: '/welcome',
parent: 'dashboard',
templateUrl: 'partials/user/dashboard/welcome'
})
.state('dashboard.account', {
url: '/account',
templateUrl: 'partials/user/dashboard/account',
controller: 'UserDashboardAccountCtrl'
})
.state('dashboard.address', {
url: '/address',
templateUrl: 'partials/user/dashboard/address/index'
})
.state('dashboard.address.view', {
url: '/view',
templateUrl: 'partials/user/dashboard/address/view',
controller: 'UserDashboardAddressViewCtrl'
})
.state('dashboard.address.new', {
url: '/new',
templateUrl: 'partials/user/dashboard/address/new',
controller: 'UserDashboardAddressNewCtrl'
})
.state('login', {
url: '/user/login',
templateUrl: 'partials/user/login',
controller: 'LoginCtrl'
})
.state('signup', {
url: '/user/signup',
templateUrl: 'partials/user/signup',
controller: 'SignupCtrl'
})
.state('settings', {
url: '/user/settings',
templateUrl: 'partials/user/settings',
controller: 'SettingsCtrl',
authenticate: true
});
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode(true);
// Intercept 401s and 403s and redirect you to login
$httpProvider.interceptors.push(['$q', '$location', function($q, $location) {
return {
'responseError': function(response) {
if(response.status === 401 || response.status === 403) {
$location.path('/user/login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
};
}]);
})
.run(function ($rootScope, $state, Auth) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){
if (toState.authenticate && !Auth.isLoggedIn()){
// User isn’t authenticated
$state.transitionTo("login");
event.preventDefault();
}
});
});
as you can see, dashboard requires authentication, how can i make it's children inherit the authenticate like dashboard.welcome , dashboard.address.view etc. with out the need to specify each one?
I know this is pretty old, but for future Googlers, note that the data property is inherited by child states, so you can place something like this authenticate flag in the parent. These modifications to your should do the trick:
For $stateProvider:
.state('dashboard', {
url: '/user/dashboard',
templateUrl: 'partials/user/dashboard/main',
controller: 'UserDashboardDashboardCtrl',
data: {
authenticate: true
}
})
For angular.module:
.run(function ($rootScope, $state, Auth) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){
if (toState.data.authenticate && !Auth.isLoggedIn()){
// User isn’t authenticated
$state.transitionTo("login");
event.preventDefault();
}
});
});
I hope this link will help, this is a great article from Frederik Nakstad about the Single Page Auth for AngularJS, sorry but not able to provide you the detail codes
http://frederiknakstad.com/2013/01/21/authentication-in-single-page-applications-with-angular-js/

Categories