/angular-hitmands-auth

Angular Module for Authentication Management

Primary LanguageJavaScriptMIT LicenseMIT

Angular Hitmands Auth

Build Status Code Climate Test Coverage

A full implementation of an Authentication System in AngularJS based Applications.

DEMO: http://hitmands.github.io/angular-hitmands-auth/


Note: Works with IE9+ (IE9 Without method AuthServiceProvider.useBasicAuthentication: see)

Note: This module requires AngularJS ^1.3 and Angular UI-Router ^0.2.

Table of Content:

## Get Started

$ bower install --save angular-hitmands-auth
<!doctype html>
<html data-ng-app="myApp">
<head>
    <!-- Install AngularJS -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.7/angular.min.js"></script>

    <!-- Install Angular UI-Router -->
    <script src="js/angular-ui-router.min.js"></script>

    <!-- Install Angular Hitmands Auth -->
    <script src="js/angular-hitmands-auth.min.js"></script>

    <!-- Create Your App-->
    <script>
        var myApp = angular.module('myApp', ['ui.router', 'hitmands.auth']);
    </script>
    ...
</head>
<body>
    ...
</body>
</html>

## Configuration

angular
    .module('myApp')
    .config(function(AuthServiceProvider, $stateProvider) {


        // Set API ENDPOINTS
        AuthServiceProvider.useRoutes({
                login: '/api/v1/users/login',
                logout: '/api/v1/users/logout',
                fetch: '/api/v1/users/logged-in'
            });

        // Callback that handles the $http Response and returns the AuthData to the AuthService
        AuthServiceProvider.parseHttpAuthData(function(data, headers, statusCode) {

            return {
                user: data,
                authLevel: authLevel, // Number|Array
                token: headers['X-AUTH-AUTHTOKEN']
            };
        });
        
        // Route Protection via data.authLevel or authLevel directly
        // authLevel {Number|Array|Function}
        // (The Function (with injectables) must return a Number or Array.
        $stateProvider
            .state({
                name: 'protected',
                url: '/protected/',
                data: {
                    authLevel: ['administrator']
                }
            });

    });

## Usage

$rootScope.currentUser = AuthService.getCurrentUser();
$rootScope.isUserLoggedIn = AuthService.isUserLoggedIn();

$rootScope.$on('hitmands.auth:update', function(event) {
    $rootScope.currentUser = AuthService.getCurrentUser();
    $rootScope.isUserLoggedIn = AuthService.isUserLoggedIn();
});

## Events Whenever a change occurs, the module generates an event via $rootScope.$broadcast method. You can register a listener via $rootScope.$on and the callback passed will be invoked with the following params:

NAME PARAMS PASSED Publisher
hitmands.auth:update event All methods that updating the CurrentUser Object
hitmands.auth:login.resolved event, result AuthService.login success
hitmands.auth:login.rejected event, error AuthService.login error
hitmands.auth:logout.resolved event, result AuthService.logout success
hitmands.auth:logout.rejected event, error AuthService.logout error
hitmands.auth:fetch.resolved event, result AuthService.fetch success
hitmands.auth:fetch.rejected event, error AuthService.fetch error
$stateChangeError event, toState, toParams, fromState, fromParams, error AuthService.authorize (when user try to access states without authorization)
$rootScope.$on('event-name', function(event[, data]) {
    // do something...
});

## Login This directive requires a FORM HTML ELEMENT, if the name attribute is set, the directive performs a basic validation. You need to pass a Javascript Object to the directive, like {username: '', password=''[, ...]}, (The properties username and password are required if the Basic Access Authentication is enabled).

Attribute Value
auth-login {Object} credentials (the payload to send)
auth-login-on-resolve {Function} A function invoked on login.success
auth-login-on-reject {Function} A function invoked on login.success
<div>
    Howdy, <strong>{{ currentUser.name || 'Guest' }}</strong>
</div>
<script>
    myApp.controller('LoginCtrl', function($scope) {
        $scope.credentials = { username: '', password: ''[, somethingElse: '']}
        $scope.loginDone = function(result) {};
        $scope.loginFail = function(error) {};
    });
</script>
<div ng-controller="LoginCtrl">

    <!-- Directive for login -->
    <form auth-login="credentials" auth-login-on-resolve="loginDone"  name="userLoginForm">
        <input type="text" required ng-model="credentials.username"/>
        <input type="password" required ng-model="credentials.password"/>
        <button class="btn btn-primary" type="submit">Login</button>
    </form>

</div>

## Logout

<!-- Directive for logout -->
<button class="btn btn-default" auth-logout>Logout</button>

## Authentication Classes

<body auth-classes>...</body>

## AuthServiceProvider.useRoutes This method configures API endpoints for login, logout, fetching authentication data.

PARAM TYPE DESCRIPTION
newRoutes Object A map of strings (login, logout, fetch) that defines the routes for user authentication.
AuthServiceProvider.useRoutes({
    login: '/api/v1/users/login.json',
    logout: '/api/v1/users/logout.json',
    fetch: '/api/v1/users/current.json'
});

## AuthServiceProvider.parseHttpAuthData This method sets a middleware between the $http responses and the AuthService.

PARAM TYPE DESCRIPTION
Callback Function This callback handles the $http responses (AuthService.login, AuthService.fetch) and returns the {user: Object, token: String, authLevel:Number/Array} to the AuthService.
AuthServiceProvider.parseHttpAuthData(function(data, headers, statusCode) {
    var authenticationData = {};

    /**
        The authenticationData Object must have the following properties:
        user = Object,
        authLevel = Number|Array,
        token = String
        The type of the authLevel property must match with the type of the authLevel
        property set on ui-router $state definition Object.
    **/

    // example:
    authenticationData.user = data.user; // Object
    authenticationData.authLevel = 1000; // Number|Array
    authenticationData.token = headers['x-authentication-token']; // String

    return authenticationData;
});

## AuthServiceProvider.tokenizeHttp This method enables the interceptor and hangs the Authentication Token to the headers of each $http request.

PARAM TYPE DESCRIPTION
headerKey (optional) String Default 'x-auth-token', the key-header for hanging the token as value
ErrorResponseInterceptor (optional) Function An interceptor invoked on ErrorResponses
AuthServiceProvider.tokenizeHttp(['X-MY-CUSTOM-AUTH-KEY'][, function(ErrorResponse) {}]);

## AuthServiceProvider.useBasicAuthentication This method enables the Basic Access Authentication for http login request.

AuthServiceProvider.useBasicAuthentication();

## AuthServiceProvider.setLoggedUser This method sets the AuthCurrentUser before your app starts to run (Angular Bootstrap Phase).

PARAM TYPE DESCRIPTION
user Object The Object for AuthCurrentUser instance.
token String The session token
authLevel Number or Array The type of this param must match with the type of the authLevel property set on ui-router $state definition Object.
AuthServiceProvider.setLoggedUser(Object, String, Number/Array);

## AuthService.setCurrentUser This method sets the AuthCurrentUser. Returns true {Boolean} if the AuthCurrentUser is instantiated, otherwise false {Boolean}.

PARAM TYPE DESCRIPTION
user Object The Object for AuthCurrentUser instance.
authLevel Number/Array The type of this param must match with the type of the authLevel property set on ui-router $state definition Object.
token String The session token
AuthService.setCurrentUser(Object, Number/Array, String);

## AuthService.unsetCurrentUser This method removes the AuthCurrentUser. Returns true {Boolean}.

AuthService.unsetCurrentUser();

## AuthService.getCurrentUser Returns AuthCurrentUser {Object} if the user is logged in, null {Null} otherwise.

AuthService.getCurrentUser();

## AuthService.getAuthenticationToken Returns {String} if the user is logged in, null {Null} otherwise.

AuthService.getAuthenticationToken();

## AuthService.isUserLoggedIn Returns {Boolean}.

AuthService.isUserLoggedIn();

## AuthService.authorize This method checks if the AuthCurrentUser is authorized, is called on each $stateChangeStart and hitmands.auth:update events. Returns {Boolean}.

PARAM TYPE DESCRIPTION
state Object The state (ui-router.$state) object.
user (optional) Object Default `AuthCurrentUser
AuthService.authorize(State, User);

## AuthService.fetch This method performs a $http GET request to routes.fetch, updates the AuthCurrentUser Object and triggers the 'hitmands.auth:fetch.success' or 'hitmands.auth:fetch.error' angular event. Returns {Promise}.

AuthService.fetch();

## AuthService.login This method performs a $http POST request to routes.login, updates the AuthCurrentUser Object and triggers the 'hitmands.auth:login.success' or 'hitmands.auth:login.error' angular event. This method is also invoked by login directive. Returns {Promise}.

PARAM TYPE DESCRIPTION
credentials Object An object to send, if the Basic Access Authentication is enabled, the following properties are required: username, password.
AuthService.login();

## AuthService.logout This method performs a $http POST request to routes.logout, removes the AuthCurrentUser Object and triggers the 'hitmands.auth:logout.success' or 'hitmands.auth:logout.error' angular event. This method is also invoked by logout directive. Returns {Promise}.

AuthService.logout()