AngularJS Partial Views Security - angularjs

I'm trying to secure the partial views so user cannot't switch views without a login but having trouble. The code is below:
var loginApp = angular.module('loginApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute'
])
//
//
//
// -------------- Cannot get this to work ------------
//
//
//
// loginApp.factory('authInterceptor', function ($q, $location) {
// debugger;
// return {
// request: function (config) {
// config.headers = config.headers | {};
// if (localStorage.auth_token) {
// config.headers.token = localStorage.auth_token;
// }
// return config;
// },
// responseError: function (response) {
//
// if (response.status === 401 || response.status === 500) {
// $location.path('/');
// }
// return $q.reject(response);
// }
// }
// })
//
// loginApp.config(function ($httpProvider) {
// $httpProvider.interceptors.push('authInterceptor');
// })
loginApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/login.html',
controller: 'loginController'
})
.when('/expertView', {
templateUrl: 'views/b.html',
controller: 'bViewController'
})
});
loginApp.controller('bViewController', function ($scope) {
//$scope.message = 'Everyone come and see how good I look!';
});
var loginController = function ($scope, $http, $location) {
$scope.user = {};
$scope.user.username = "name";
$scope.user.userID = "123456";
$scope.user.password = "444444444";
$scope.user.ui = "true";
$scope.user.submitForm = function (item, event) {
var data = {
userID: $scope.user.userID,
password: $scope.user.password,
ui: $scope.user.ui
};
$http({
url: '/api/v1/auth/login',
method: "POST",
dataType: "json",
data: data,
headers: {
'Accept': 'application/json, text/javascript',
'Content-Type': 'application/json; charset=utf-8'
}
}).success(function (data, status, headers, config) {
console.log("Success!");
}).error(function (data, status, headers, config) {
console.log("Submitting to Server failed!");
});
}
}
I just need to secure the views and make sure user cannot (switch) access views without login.

First create a constant that can determine the access level for each route for example
angular.module("App")
.constant('USER_ROLES', {
logedIn : 'true'
});
then add them to the definition of the route as
.when('/write',{
templateUrl:'templates/write.html',
access_level:USER_ROLES.logedIn
})
After that in the run function check $rootScope.$on('$locationChangeStart' event and inside it you can access the route by var location = $location.path(); var route = $route.routes[location];and then access the user role by route.access_level;

Related

Store data from controller to service in angularjs

Although there are many questions regarding the subject , yet I am unable to figure it out , how to proceed further.
I am new in AngularJS. I want to pass data coming from API in Controller and pass it to another function. For this I know I have to create a Service. But after coming to this extend of code I am unable to figure it, how to store it in Service and pass it on other Controller or of function within same Controller. I am new in making Service.
Controller:
$scope.GetR = function (){
$scope.X = null;
$scope.Y = null;
$http({method: 'POST', url: 'http://44.43.3.3/api/infotwo',
headers: {"Content-Type": "application/json"},
data: $scope.ResponseJson
})
.success(function(data, status, headers, config) {
$scope.X = data.X;
$scope.Y = data.Y;
//console.log($scope.X+"and"+$scope.Y);
//Seding RS to API to get AAs
$scope.RJson = {
"ICl": $scope.ICl,
"RS": $scope.X
};
$http({method: 'POST', url: 'http://44.128.44.5/api/apithree',
headers: {"Content-Type": "application/json"},
data: $scope.RJson
})
.success(function(data, status, headers, config) {
$scope.At = data;
$scope.Eq = data.AA.Eq;
$scope.FIn = data.AA.FIn;
$scope.MM = data.AA.MM;
console.log("Eq:"+$scope.Eq+" FIn:"+$scope.FIn+" MM:"+$scope.MM);
}).error(function(data, status, headers, config) {
console.log("API failed...");
});
}).error(function(data, status, headers, config) {
console.log("Something went wrong...");
});
};
Now I want to pass this data to Service so that I can call this output on other API input
.success(function(data, status, headers, config) {
$scope.At = data;
$scope.Eq = data.AA.Eq;
$scope.FIn = data.AA.FIn;
$scope.MM = data.AA.MM;
console.log("Eq:"+$scope.Eq+" FIn:"+$scope.FIn+" MM:"+$scope.MM);
This shows how to create a service and share data between two controllers.
The service:
(function() {
'use strict';
angular
.module('myAppName') // Replace this to your module name
.service('MyService', MyService);
MyService.$inject = [];
function MyService() {
this.data = null;
}
})();
First controller:
(function() {
'use strict';
angular
.module('myAppName') // Replace this to your module name
.controller('MyFirstController', MyFirstController);
MyFirstController.$inject = ['MyService', '$http'];
function MyFirstController(MyService, $http) {
var vm = this;
vm.data = MyService.data;
$http.post('/someUrl', whatEverData).then(resp=> {
MyService.data = resp.data;
})
}
})();
Second controller:
(function() {
'use strict';
angular
.module('myAppName') // Replace this to your module name
.controller('MySecondController', MySecondController);
MySecondController.$inject = ['MyService', '$http'];
function MySecondController(MyService, $http) {
var vm = this;
vm.data = MyService.data; // Here you can use the same data
}
})();
Not sure if this is what you are looking for. Below code is not tested (May have syntax errors)
Service:
function() {
'use strict';
angular
.module('myAppName')
.factory('MyService', MyService);
MyService.$inject = [];
function MyService() {
var data = null;
return {
getData: function() {
return data;
},
setData: function(d) {
data = d;
}
}
}
})();
Controller:
(function() {
'use strict';
angular
.module('myAppName')
.factory('controller', controller);
controller.$inject = ['$scope', '$http', 'MyService'];
function controller($scope, $http, MyService) {
$scope.GetR = function() {
$scope.X = null;
$scope.Y = null;
var promise = $http({
method: 'POST',
url: 'http://44.43.3.3/api/infotwo',
headers: {
"Content-Type": "application/json"
},
data: $scope.ResponseJson
});
promise.success(function(data, status, headers, config) {
$scope.X = data.X;
$scope.Y = data.Y;
//console.log($scope.X+"and"+$scope.Y);
//Seding RS to API to get AAs
$scope.RJson = {
"ICl": $scope.ICl,
"RS": $scope.X
};
}).error(function(data, status, headers, config) {
console.log("Something went wrong...");
});
return promise;
};
$scope.sendRS = function() {
var promise = $http({
method: 'POST',
url: 'http://44.128.44.5/api/apithree',
headers: {
"Content-Type": "application/json"
},
data: $scope.RJson
});
promise.success(function(data, status, headers, config) {
$scope.At = data;
$scope.Eq = data.AA.Eq;
$scope.FIn = data.AA.FIn;
$scope.MM = data.AA.MM;
console.log("Eq:" + $scope.Eq + " FIn:" + $scope.FIn + " MM:" + $scope.MM);
}).error(function(data, status, headers, config) {
console.log("API failed...");
});
return promise;
}
var init = function() {
$scope.GetR().then(function() {
$scope.sendRS().then(function(data) {
MyService.setData({
At: data,
Eq: data.AA.Eq,
FIn: data.AA.FIn,
MM: data.AA.MM
});
})
})
}
init();
}
})();
Other controller
(function() {
'use strict';
angular
.module('myAppName')
.controller('controller1', controller1);
controller1.$inject = ['$scope', 'MyService'];
function controller1($scope, MyService) {
$scope.data = MyService.getData();
}
})();

separated controller from component

Component:
crudModule.js
var crudModule = angular.module('crudModule', ['ui.router', 'smart-table', 'ngCookies', 'ui.bootstrap', 'angularModalService', 'dialogs', 'remoteValidation']);
angular.module('crudModule').component('applicationInfo', {
templateUrl: 'infoApplication.html',
controller: 'applicationInfoCtrl'
});
applicationInfoCtrl.js:
var crudModule = angular.module('crudModule')
crudModule.controller('applicationInfoCtrl', ['httpService', '$scope', function($http, $scope, $cookies, $stateParams, httpService) {
httpService.httpGetRequest("http://localhost:8080/applications/" + $stateParams.id).then(function success(response) {
$scope.application = response.data;
});
$scope.getApiKey = function () {
httpService.httpGetRequest('http://localhost:8080/applications/generateApiKey').then(function success(response) {
$scope.application.apikey = response.data.apikey;
$scope.application.apisecret = response.data.apisecret
})
};
$scope.send = function (object, url) {
httpService.httpPostRequest(object, url + "/" + $stateParams.id).catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
}).then(function success(response){
});
}
}]);
httpService.js:
var crudModule = angular.module('crudModule')
crudModule.factory('httpService', function($http) {
return {
httpGetRequest: function (url) {
return $http({
method: 'GET',
url: url
})
},
httpPostRequest: function (object, url){
return $http({
method:'POST',
url: url,
data: object
})
}
}
});
I am getting error:
Cannot read property 'httpGetRequest' of undefined.
I have injected my httpService and i dont find any mistakes yet
The problem is the order of parameters in your controller, it should be
crudModule.controller('applicationInfoCtrl', ['$http','httpService', '$scope','$cookies','$stateParams' function(http,httpService, $scope,$cookies,$stateParams) {
}

Unit Test Angular http.post with Data in Header

I am trying to write a unit test for service that performs a http.post to an api that passes credentials in the header.
Controller:
app.controller('LoginController', function($scope, $http, signInService) {
$scope.LogIn = function(usrnm, pwd) {
signInService.authUser(usrnm, pwd)
.success(function (data, status, headers, config) {
// Display success message
$scope.gotToAddress = data.successUrl;
})
.error(function (data, status, headers, config) {
// Display error message
}
}
});
signInService:
app.service('signInService', function($http) {
this.authUser = function (usrnm, pwd) {
return $http({
url: '/api/json/authenticate',
method: "POST",
data: '{}',
headers: {
'Content-Type': 'application/json',
'X-app-Username': usrnm,
'X-app-Password': pwd
}
});
};
});
Unit test:
describe('mocking service http call', function() {
beforeEach(module('myApp'));
var LoginController, $scope;
describe('with httpBackend', function() {
beforeEach(inject(function($controller, $rootScope, $httpBackend) {
$scope = $rootScope.$new();
$httpBackend.when('POST', '/api/json/authenticate', {}, function(headers) {
return {
'Content-Type': 'application/json',
'X-app-Username': 'admin',
'X-app-Password': 'admin'
};
}).respond(200)
LoginController = $controller('LoginController', { $scope: $scope });
$httpBackend.flush();
}));
it('should set data to "things and stuff"', function() {
expect($scope.data).toEqual({things: 'and stuff'});
});
});
});
When running the test i am seeing the following error: mocking service http call ยป with httpBackend
Error: No pending request to flush !
Controller with service on .succeed:
app.controller('LoginController', function($scope, $http, signInService, cookieSrv) {
$scope.LogIn = function(usrnm, pwd) {
signInService.authUser(usrnm, pwd)
.success(function (data, status, headers, config) {
// Display success message
var cookieID = 'myCookie';
cookieSrv.createCookie(cookieID, data.token, 3, data.redirectUrl);
})
.error(function (data, status, headers, config) {
// Display error message
}
}
});
cookieSrv.js
app.service('cookieSrv', function() {
return {
createCookie : function(cookieID, token, days, redirectUrl) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = cookieID+"="+token+expires+"; path=/";
window.location.assign(redirectUrl)
}
}
});
Your controller defines a method logIn on the $scope but you do not call this function in the test, and hence actual http request is not made.
Modify the test by calling $scope.logIn before you call flush
LoginController = $controller('LoginController', { $scope: $scope });
$scope.logIn("Test","test"); // Add this
$httpBackend.flush();

UI-router won't resolve promise

I'm not quite sure what I'm doing wrong, but it seems that my profile doesn't resolve by the time we get to the MainCtrl. The user however does, resolve. Am I, perhaps not fetching the profile information properly in the Auth Service?
Router:
angular.module('app')
.config(function ($stateProvide) {
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'app/main/main',
controller: 'MainCtrl',
resolve: {
user: function (Auth) {
return Auth.getUser();
},
profile: function (user) {
return Auth.getProfile();
}
}
});
});
Controller:
angular.module('app')
.controller('MainCtrl', function ($scope, user, profile) {
$scope.user = user;
$scope.profile = profile; <- DOESNT RESOLVE
});
Auth Service:
angular.module('app')
.factory('Auth', function ($firebaseSimpleLogin, $firebase, FBURL) {
var ref = new Firebase(FBURL);
var auth = $firebaseSimpleLogin(ref);
var Auth = {
user: {},
getUser: function () {
return auth.$getCurrentUser();
},
getProfile: function(uid) {
return $firebase(ref.child('users').child(uid)).$asObject();
}
};
return Auth;
});
Something like
auth.$getCurrentUser()
returns a promise so you need a
.then(function(user) {
event before your callback complete
In your case you may just resolve on the then, something like
Auth.getUser().then(function(user){ return user; });
Also $asObject() needs $loaded() for it's promise
var obj = $firebase(ref).$asObject();
obj.$loaded()
.then(function(data) {})
Try this structure for your promises:
var fetchSomething = function (action, params) {
var promise = $http({
method: 'POST',
url: 'someurl to the firebase',
data: params,
headers: {
'Access-Control-Allow-Origin': true,
'Content-Type': 'application/json'
}
}).success(function (data, status, headers, config) {
return data;
});
return promise;
};

Why Dependency injection of a factory inside another factory failing?

I have one factory like this :
app.factory('LoginFactory', [ '$scope', '$http', function($scope, $http) {
var urlBase = "http://localhost:8080/app";
var fact = {};
fact.login = function(userinfo) {
return $http({
method : 'POST',
url : urlBase + '/login',
data : userinfo,
headers : {
'Content-Type' : 'application/json',
'Accept' : 'application/json'
}
});
};
fact.validate = function(sessionId) {
return $http({
method : 'GET',
url : urlBase + '/validate?sessionId=' + sessionId,
});
};
return fact;
} ]);
And Another factory like this :
app.factory('LoginService', [
'Credentials',
function(Credentials, $location, LoginFactory) {
var fact = {};
fact.isLoggedin = function() {
var result = false;
LoginFactory.validate(Credentials.sessionId).success(
function(data, status, headers, config) {
result = true;
}).error(function(data, status, headers, config) {
result = false;
});
return result;
};
fact.authenticate = function(userinfo) {
LoginFactory.login(userinfo).success(
function(data, status, headers, config) {
Credentials = data;
$location.path('/home');
}).error(function(data, status, headers, config) {
$location.path('/login');
});
};
return fact;
} ]);
In the Browser Console I am getting the following error :
Error: LoginFactory is undefined
Can anyone please help me out with this error.
Thanks a lot in advance.
You're declaring your service using the array notation, taking the names of the dependencies to inject followed by the function defining the factory. But you said you only wanted to inject Credentials:
app.factory('LoginService', [
'Credentials',
function(Credentials, $location, LoginFactory) {
So angular only injects Credentials. The above should be replaced by
app.factory('LoginService', [
'Credentials', '$location', 'LoginFactory'
function(Credentials, $location, LoginFactory) {
To avoid those bugs, and the repetition of service names in the array and in the function, I strongly suggest using ngAnnotate in your build.

Resources