Mittwoch, 26. Februar 2014

Draft: Refactoring app.Initialize() of app.viewmodel.js

When a user does his first attempt to connect to the SPA or refreshes his browser one of the first hookups is the call of self.initialize() of app.viewmodel.js by  app.initialize() within _run.js.

Some examination of the initialization code in conjunction with the corresponding AccountController on the server side made it clear to me that it is entirley about local or external authentication and some navigation instructions when the user tried an unauthorized access or is already logged in.

The very first draft tries to extract and encapsulate the authentication code and make the code more readable in terms of workflow processing.

file: app.viewmodel.js

var app = new AppViewModel(new AppDataModel());

function AppViewModel(dataModel) {

// Private state
var self = this

//-- register authentication management
var authentication = AppAuthentication;  

//Navigation behaviour when it comes to access denied authentication
function NavigationBehaviourAccessDenied(data) {
      self.navigateToLogin();
}

//Navigation behaviour when it comes to already logged in authentication
function NavigationBehaviourAlreadyLoggedIn(data) {
   if (data.userName) {
      self.navigateToLoggedIn(data.userName);
   } else {
      self.navigateToLogin();
   }
}  

authentication.OnAlreadyLoggedIn = NavigationBehaviourAlreadyLoggedIn;
authentication.OnAccessDenied = NavigationBehaviourAccessDenied;
//-- end of register authentication Management

...

self.initialize = function () {
    Authenticate();
}

function Authenticate() {
   var loginType = sessionStorage["associatingExternalLogin"];
   var fragment = AppAuthentication.GetFragment();
   

   if (typeof (loginType) === "undefined") {
        authentication.AuthenticateLocal();
   }

   if (loginType) {
        AuthenticateExternal();
   }

}
...
}


file: app.authentication.js

//application authentication
var AppAuthentication = {
    OnAlreadyLoggedIn: null,
    OnAccessDenied: null,  

    AuthenticateLocal: function()
    {
        var userInfoUrl = "/api/Account/UserInfo";
        var authenticateUser = function (accessToken) {
                    var headers;
                    if (typeof (accessToken) !== "undefined") {
                        headers = {
                            "Authorization": "Bearer " + accessToken
                        };
                    } else {
                        headers = AppAuthenticationHelper.GetSecurityHeaders();
                    }            
            $.ajax(userInfoUrl, {
                cache: false,
                headers: headers
            }).done(AppAuthentication.OnAlreadyLoggedIn).fail(AppAuthentication.OnAccessDenied);
        }; 
        return authenticateUser();    
    }};


file: app.authentication.helper.js

//application authentication helper
var AppAuthenticationHelper = { 
 GetFragment:  function ()
 {
  return GetFragmentItem();

  function GetFragmentItem() {
   if (window.location.hash.indexOf("#") === 0) {
    return AppAuthenticationHelper.ParseQueryString(window.location.hash.substr(1));
   } else {
    return {};
   }
  }
 },

 GetSecurityHeaders: function() {
  var accessToken = sessionStorage["accessToken"] || localStorage["accessToken"];
  if (accessToken) {
  return { "Authorization": "Bearer " + accessToken };
  }
  return {};
 },

 ParseQueryString: function (queryString) {
     var data = {},
         pairs, pair, separatorIndex, escapedKey, escapedValue, key, value;

     if (queryString === null) {
         return data;
     }

     pairs = queryString.split("&");

     for (var i = 0; i < pairs.length; i++) {
         pair = pairs[i];
         separatorIndex = pair.indexOf("=");

         if (separatorIndex === -1) {
             escapedKey = pair;
             escapedValue = null;
         } else {
             escapedKey = pair.substr(0, separatorIndex);
             escapedValue = pair.substr(separatorIndex + 1);
         }

         key = decodeURIComponent(escapedKey);
         value = decodeURIComponent(escapedValue);

         data[key] = value;
     }

     return data;
 }
};

Keine Kommentare:

Kommentar veröffentlichen