wrath1888
wrath1888

Reputation: 49

Angular. Authentication is not checked

Authentication is not checked in my angular app. User should not have access to "car" & "profile" views without login but now i can get to it. I've added "secure" property to the pages that should be hidden from non-authenticated user. I've added check for apprun in app.js. But it does not work.

here's services.js

    'use strict';
angular.module('myApp')
.service('carsSrv', function () {
  var carList = [];

  var addUserCar = function (currObj, title, color, description, image) {
    currObj = {
        title: title,
        color: color,
        descriptiopn: description,
        image: image
      };
      /* console.log("Car Added:  " + currObj.id + "\n" + currObj.title + "\n" + currObj.color + "\n" + currObj.description + "\n" + currObj.image);*/
    carList.push(currObj);
    console.log(carList);
  };

  var getCars = function () {
    console.log("User cars");
    console.log(carList);
    return carList;

  };

  return {
    addUserCar: addUserCar,
    getCars: getCars
  }


})
.service('userSrv', userSrv)
.provider('storageSrv',storageSrv);
    function userSrv(storageSrv, carsSrv) {
      var user = {name: '', cars: carsSrv.carList };
      this.getUser = function() {
          return user;
      };

      this.getUserName = function () {
          return user.name;
      };
      this.login = function(){
        user.name = 'test name';
        user.cars = init();
        storageSrv.updateData(user);
                return true;

      }
      this.logout = function(){
        user.name = '';
        user.cars = [];
        alert('User logs out');
        storageSrv.updateData(user);
      }
      this.checkLoginUser = function(){
        return user.name !='';
      }
      this.getUserFeatures = function(){
        return user.features;
      }
      this.registration = function(){
        user.name = name;
        user.cars = init();
      }
      function init(){
        return storageSrv.getData();
      }

    }



  function storageSrv(){
    var storageName = 'cars';
    return {
      configStorageName : configStorageName,
      $get:$get
    };

    function configStorageName(name){
      if(name){
        storageName = name;
        return this;
      }
      else{
        return storageName;
      }
    }

    function $get(){
      function updateStorage(data){
        localStorage.setItem(storageName, data);
      }
      function getStorage(){
        return localStorage.getItem(storageName);
      }
      function updateData(data){
        console.log('storageName ' + storageName);
        updateStorage(JSON.stringify(data));
      }
      function getData(){
        console.log('storageName ' + storageName);
        var data = getStorage();
        return JSON.parse(data) || [];
      }
      return {
        updateData: updateData,
        getData:getData
      }
    }
  };

and here's app.js

    'use strict';

// Declare app level module which depends on views, and components
angular.module('myApp', [
    'ngRoute'
])
    .constant('STORAGE_NAME', 'USER_CARS')
    .config(configStorage)
    .config(configRoutes)

.controller('carsCtrl', ['$scope', '$http', 'carsSrv',
    function($scope, $http, carsSrv) {
        $scope.view = "Cars";
        $http.get('cars/cars.json')
            .success(function(data) {

                $scope.cars = data;

                $scope.addCar = function(id, title, color, description, image) {
                    carsSrv.addUserCar(id, title, color, description, image);
                };

            })
            .error(function() {
                alert("can not get data from cars.json");
            });
    }
])

.controller('homeCtrl', ['$scope',

    function($scope) {
        $scope.view = "Home";
    }
])

.controller('loginCtrl', ['userSrv', '$scope',
    function(userSrv, $scope) {
        $scope.view = "Login";
        $scope.userLogin = function() {
            userSrv.login();

        }
        $scope.userLogout = function() {
            userSrv.logout();

        }

    }
])

.controller('profileCtrl', ['$scope', 'carsSrv',
    function($scope, carsSrv) {
        $scope.view = "Profile";
        $scope.userCars = carsSrv.getCars();


    }
]);

function configStorage(storageSrvProvider, STORAGE_NAME) {
    console.log(storageSrvProvider);
    storageSrvProvider.configStorageName(STORAGE_NAME);
}

function configRoutes($routeProvider) {
    $routeProvider

    .when('/cars', {
        templateUrl: 'views/cars.html',
        controller: 'carsCtrl',
        secure: true
    })

    .when('/profile', {
        templateUrl: 'views/profile.html',
        controller: 'profileCtrl',
        secure: true
    })

    .when('/home', {
        templateUrl: 'views/home.html',
        controller: 'homeCtrl',
        secure: false
    })

    .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'loginCtrl',
        secure: false
    })



    .otherwise({
        redirectTo: '/home'
    });
}

var appRun = function($rootScope, $location, $userSrv) {
    $rootScope.on('$routeChangeStart', function(event, next) {
        if (next.secure && !userSrv.checkLoginUser()) {
            $location.path('/login');
        }
    });
};

Upvotes: 0

Views: 78

Answers (1)

Pedro M. Silva
Pedro M. Silva

Reputation: 1298

Your not really running the code appRun. Try adding this last line to your module declaration:

angular.module('myApp', [
    'ngRoute'
])
    .constant('STORAGE_NAME', 'USER_CARS')
    .config(configStorage)
    .config(configRoutes)
    .run(appRun);

Also, because appRun is a variable containing an anonymous function, and not a function named appRun, by the time you call the run(appRun) (at the beginning of the file) the variable is defined but still undefined. That is why the function is not running.

Also, when listening to the event, you're using a function $rootScope.on(), instead of the correct name $rootScope.$on(). Apart from that, I tested it on my computed and it seems to be working.

function checkRoute ( userSrv, $location, current ) {
    if (current.secure && !userSrv.checkLoginUser()) {
        $location.path('/login');
    }
}

function appRun ($rootScope, $route, $location, userSrv) {
    $rootScope.$on('$routeChangeStart', function(event, next) {
        checkRoute(userSrv, $location, next);
    });

    $rootScope.$on('sessionLogout', function () {
        checkRoute(userSrv, $location, $route.current);
    });
};

Update: For the logout to work, one strategy is to emit an event when logging out and then listen for that even and do the same check to see if the page is secure or not.

function userSrv($rootScope, storageSrv, carsSrv) {
    //...
    this.logout = function(){
        user.name = '';
        user.cars = [];
        alert('User logs out');
        storageSrv.updateData(user);

        // Emit an event notifying the application that
        // the user has logged out
        $rootScope.$emit('sessionLogout');
    }
    //...
}

Upvotes: 1

Related Questions