From 663ba92054e6b217a5af890fbe8f1a94be9ec659 Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Thu, 23 Apr 2015 18:19:07 -0600
Subject: [PATCH 01/11] Add localStorage and sessionStorage to providers

---
 dist/angular-oauth2.js                | 68 ++++++++++++++++++++++++--
 dist/angular-oauth2.min.js            |  2 +-
 src/providers/oauth-provider.js       |  2 +-
 src/providers/oauth-token-provider.js | 69 +++++++++++++++++++++++++--
 4 files changed, 131 insertions(+), 10 deletions(-)

diff --git a/dist/angular-oauth2.js b/dist/angular-oauth2.js
index 60bdac2..acc8912 100644
--- a/dist/angular-oauth2.js
+++ b/dist/angular-oauth2.js
@@ -179,8 +179,10 @@
         if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
     };
     function OAuthTokenProvider() {
+        var storage;
         var config = {
             name: "token",
+            storage: "cookies",
             options: {
                 secure: true
             }
@@ -198,10 +200,10 @@
                 _prototypeProperties(OAuthToken, null, {
                     token: {
                         set: function(data) {
-                            return ipCookie(config.name, data, config.options);
+                            return setToken(data);
                         },
                         get: function() {
-                            return ipCookie(config.name);
+                            return getToken();
                         },
                         enumerable: true,
                         configurable: true
@@ -242,9 +244,17 @@
                         configurable: true
                     },
                     removeToken: {
-                        value: function removeToken() {
-                            return ipCookie.remove(config.name, config.options);
-                        },
+                        value: function(_removeToken) {
+                            var _removeTokenWrapper = function removeToken() {
+                                return _removeToken.apply(this, arguments);
+                            };
+                            _removeTokenWrapper.toString = function() {
+                                return _removeToken.toString();
+                            };
+                            return _removeTokenWrapper;
+                        }(function() {
+                            return removeToken();
+                        }),
                         writable: true,
                         enumerable: true,
                         configurable: true
@@ -252,6 +262,54 @@
                 });
                 return OAuthToken;
             }();
+            var setToken = function(data) {
+                storage = config.storage.toLowerCase();
+                switch (storage) {
+                  case "cookies":
+                    return ipCookie(config.name, data, config.options);
+
+                  case "localstorage":
+                    return localStorage.setItem(config.name, JSON.stringify(data));
+
+                  case "sessionstorage":
+                    return sessionStorage.setItem(config.name, JSON.stringify(data));
+
+                  default:
+                    return ipCookie(config.name, data, config.options);
+                }
+            };
+            var getToken = function() {
+                storage = config.storage.toLowerCase();
+                switch (storage) {
+                  case "cookies":
+                    return ipCookie(config.name);
+
+                  case "localstorage":
+                    return JSON.parse(localStorage.getItem(config.name));
+
+                  case "sessionstorage":
+                    return JSON.parse(sessionStorage.getItem(config.name));
+
+                  default:
+                    return ipCookie(config.name);
+                }
+            };
+            var removeToken = function() {
+                storage = config.storage.toLowerCase();
+                switch (storage) {
+                  case "cookies":
+                    return ipCookie.remove(config.name, config.options);
+
+                  case "localstorage":
+                    return localStorage.removeItem(config.name);
+
+                  case "sessionstorage":
+                    return sessionStorage.removeItem(config.name);
+
+                  default:
+                    return ipCookie.remove(config.name, config.options);
+                }
+            };
             return new OAuthToken();
         };
         this.$get.$inject = [ "ipCookie" ];
diff --git a/dist/angular-oauth2.min.js b/dist/angular-oauth2.min.js
index 4f8020c..d892aea 100644
--- a/dist/angular-oauth2.min.js
+++ b/dist/angular-oauth2.min.js
@@ -1 +1 @@
-!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e){e.interceptors.push("oauthInterceptor")}function n(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},c,t),e.forEach(s,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var i=function(){function i(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(i,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(i,a){if(!i||!i.username||!i.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:i.username,password:i.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),a=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},a),n.post(""+r.baseUrl+r.grantPath,u,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,i).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),i}();return new i},this.$get.$inject=["$http","OAuthToken"]}function i(){var t={name:"token",options:{secure:!0}};this.configure=function(r){if(!(r instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(t,r),t},this.$get=function(e){var r=function(){function r(){}return u(r,null,{token:{set:function(r){return e(t.name,r,t.options)},get:function(){return e(t.name)},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(){return e.remove(t.name,t.options)},writable:!0,enumerable:!0,configurable:!0}}),r}();return new r},this.$get.$inject=["ipCookie"]}var a=e.module("angular-oauth2",["ipCookie"]).config(r).factory("oauthInterceptor",n).provider("OAuth",o).provider("OAuthToken",i);r.$inject=["$httpProvider"],n.$inject=["$q","$rootScope","OAuthToken"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},c={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},s=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return a});
\ No newline at end of file
+!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e){e.interceptors.push("oauthInterceptor")}function n(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(e){var n=function(){function e(){}return u(e,null,{token:{set:function(e){return o(e)},get:function(){return a()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return i()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),o=function(n){switch(t=r.storage.toLowerCase()){case"cookies":return e(r.name,n,r.options);case"localstorage":return localStorage.setItem(r.name,JSON.stringify(n));case"sessionstorage":return sessionStorage.setItem(r.name,JSON.stringify(n));default:return e(r.name,n,r.options)}},a=function(){switch(t=r.storage.toLowerCase()){case"cookies":return e(r.name);case"localstorage":return JSON.parse(localStorage.getItem(r.name));case"sessionstorage":return JSON.parse(sessionStorage.getItem(r.name));default:return e(r.name)}},i=function(){switch(t=r.storage.toLowerCase()){case"cookies":return e.remove(r.name,r.options);case"localstorage":return localStorage.removeItem(r.name);case"sessionstorage":return sessionStorage.removeItem(r.name);default:return e.remove(r.name,r.options)}};return new n},this.$get.$inject=["ipCookie"]}var i=e.module("angular-oauth2",["ipCookie"]).config(r).factory("oauthInterceptor",n).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$httpProvider"],n.$inject=["$q","$rootScope","OAuthToken"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file
diff --git a/src/providers/oauth-provider.js b/src/providers/oauth-provider.js
index da2c5e2..122f1fb 100644
--- a/src/providers/oauth-provider.js
+++ b/src/providers/oauth-provider.js
@@ -167,8 +167,8 @@ function OAuthProvider() {
         };
 
         return $http.post(`${config.baseUrl}${config.grantPath}`, data, options).then((response) => {
+          
           OAuthToken.token = response.data;
-
           return response;
         });
       }
diff --git a/src/providers/oauth-token-provider.js b/src/providers/oauth-token-provider.js
index 5fbb530..432288d 100644
--- a/src/providers/oauth-token-provider.js
+++ b/src/providers/oauth-token-provider.js
@@ -10,8 +10,10 @@ import angular from 'angular';
  */
 
 function OAuthTokenProvider() {
+  var storage;
   var config = {
     name: 'token',
+    storage: 'cookies',//cookies,localStorage,sessionStorage
     options: {
       secure: true
     }
@@ -49,7 +51,7 @@ function OAuthTokenProvider() {
        */
 
       set token(data) {
-        return ipCookie(config.name, data, config.options);
+        return setToken(data);
       }
 
       /**
@@ -57,7 +59,7 @@ function OAuthTokenProvider() {
        */
 
       get token() {
-        return ipCookie(config.name);
+        return getToken();
       }
 
       /**
@@ -101,10 +103,71 @@ function OAuthTokenProvider() {
        */
 
       removeToken() {
-        return ipCookie.remove(config.name, config.options);
+        return removeToken();
       }
+
     }
 
+    /**
+     * setToken
+     *
+     * @param data
+     * @returns {*}
+     */
+    var setToken = function(data) {
+     storage = config.storage.toLowerCase();
+      switch (storage) {
+       case 'cookies':
+        return ipCookie(config.name, data, config.options);
+       case 'localstorage':
+        return localStorage.setItem(config.name,JSON.stringify(data));
+       case 'sessionstorage':
+        return sessionStorage.setItem(config.name,JSON.stringify(data));
+       default :
+        return ipCookie(config.name, data, config.options);
+      }
+    };
+
+    /**
+     * getToken
+     *
+     * @returns {*}
+     */
+    var getToken = function() {
+     storage = config.storage.toLowerCase();
+      switch (storage) {
+       case 'cookies':
+        return ipCookie(config.name);
+       case 'localstorage':
+        return JSON.parse(localStorage.getItem(config.name));
+       case 'sessionstorage':
+        return JSON.parse(sessionStorage.getItem(config.name));
+       default :
+        return ipCookie(config.name);
+
+      }
+    };
+
+    /**
+     * removeToken
+     *
+     * @returns {*}
+     */
+    var removeToken = function() {
+     storage = config.storage.toLowerCase();
+      switch (storage) {
+       case 'cookies':
+        return ipCookie.remove(config.name, config.options);
+          case 'localstorage':
+            return localStorage.removeItem(config.name);
+          case 'sessionstorage':
+            return sessionStorage.removeItem(config.name);
+          default :
+            return ipCookie.remove(config.name, config.options);
+
+      }
+    };
+
     return new OAuthToken();
   };
 }

From d9bf178320711bb574c4dfdbdf52738cbd8685a0 Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Thu, 23 Apr 2015 19:23:21 -0600
Subject: [PATCH 02/11] update README

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 70c329e..2eb30b8 100644
--- a/README.md
+++ b/README.md
@@ -153,6 +153,7 @@ Configuration defaults:
 ```js
 OAuthTokenProvider.configure({
   name: 'token',
+  storage:'cookies' // options: 'cookies','localstorage','sessionstorage'
   options: {
     secure: true
   }

From e2926988ca0bbc8957c3f9d6eee5eb438f949a49 Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Wed, 9 Sep 2015 14:46:46 -0600
Subject: [PATCH 03/11] enhance code and refactor changes

---
 dist/angular-oauth2.js                | 16 ++++++++--------
 dist/angular-oauth2.min.js            |  2 +-
 src/providers/oauth-provider.js       |  2 +-
 src/providers/oauth-token-provider.js | 12 ++++++------
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/dist/angular-oauth2.js b/dist/angular-oauth2.js
index acc8912..5f8c90b 100644
--- a/dist/angular-oauth2.js
+++ b/dist/angular-oauth2.js
@@ -14,10 +14,6 @@
     }
 })(this, function(angular, queryString) {
     var ngModule = angular.module("angular-oauth2", [ "ipCookie" ]).config(oauthConfig).factory("oauthInterceptor", oauthInterceptor).provider("OAuth", OAuthProvider).provider("OAuthToken", OAuthTokenProvider);
-    function oauthConfig($httpProvider) {
-        $httpProvider.interceptors.push("oauthInterceptor");
-    }
-    oauthConfig.$inject = [ "$httpProvider" ];
     function oauthInterceptor($q, $rootScope, OAuthToken) {
         return {
             request: function(config) {
@@ -40,6 +36,10 @@
         };
     }
     oauthInterceptor.$inject = [ "$q", "$rootScope", "OAuthToken" ];
+    function oauthConfig($httpProvider) {
+        $httpProvider.interceptors.push("oauthInterceptor");
+    }
+    oauthConfig.$inject = [ "$httpProvider" ];
     var _prototypeProperties = function(child, staticProps, instanceProps) {
         if (staticProps) Object.defineProperties(child, staticProps);
         if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
@@ -269,10 +269,10 @@
                     return ipCookie(config.name, data, config.options);
 
                   case "localstorage":
-                    return localStorage.setItem(config.name, JSON.stringify(data));
+                    return localStorage.setItem(config.name, angular.toJson(data));
 
                   case "sessionstorage":
-                    return sessionStorage.setItem(config.name, JSON.stringify(data));
+                    return localStorage.setItem(config.name, angular.toJson(data));
 
                   default:
                     return ipCookie(config.name, data, config.options);
@@ -285,10 +285,10 @@
                     return ipCookie(config.name);
 
                   case "localstorage":
-                    return JSON.parse(localStorage.getItem(config.name));
+                    return angular.fromJson(localStorage.getItem(config.name));
 
                   case "sessionstorage":
-                    return JSON.parse(sessionStorage.getItem(config.name));
+                    return angular.fromJson(sessionStorage.getItem(config.name));
 
                   default:
                     return ipCookie(config.name);
diff --git a/dist/angular-oauth2.min.js b/dist/angular-oauth2.min.js
index d892aea..af83d5e 100644
--- a/dist/angular-oauth2.min.js
+++ b/dist/angular-oauth2.min.js
@@ -1 +1 @@
-!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e){e.interceptors.push("oauthInterceptor")}function n(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(e){var n=function(){function e(){}return u(e,null,{token:{set:function(e){return o(e)},get:function(){return a()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return i()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),o=function(n){switch(t=r.storage.toLowerCase()){case"cookies":return e(r.name,n,r.options);case"localstorage":return localStorage.setItem(r.name,JSON.stringify(n));case"sessionstorage":return sessionStorage.setItem(r.name,JSON.stringify(n));default:return e(r.name,n,r.options)}},a=function(){switch(t=r.storage.toLowerCase()){case"cookies":return e(r.name);case"localstorage":return JSON.parse(localStorage.getItem(r.name));case"sessionstorage":return JSON.parse(sessionStorage.getItem(r.name));default:return e(r.name)}},i=function(){switch(t=r.storage.toLowerCase()){case"cookies":return e.remove(r.name,r.options);case"localstorage":return localStorage.removeItem(r.name);case"sessionstorage":return sessionStorage.removeItem(r.name);default:return e.remove(r.name,r.options)}};return new n},this.$get.$inject=["ipCookie"]}var i=e.module("angular-oauth2",["ipCookie"]).config(r).factory("oauthInterceptor",n).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$httpProvider"],n.$inject=["$q","$rootScope","OAuthToken"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file
+!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function n(e){e.interceptors.push("oauthInterceptor")}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(n){var o=function(){function e(){}return u(e,null,{token:{set:function(e){return a(e)},get:function(){return i()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return s()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),a=function(o){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name,o,r.options);case"localstorage":return localStorage.setItem(r.name,e.toJson(o));case"sessionstorage":return localStorage.setItem(r.name,e.toJson(o));default:return n(r.name,o,r.options)}},i=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name);case"localstorage":return e.fromJson(localStorage.getItem(r.name));case"sessionstorage":return e.fromJson(sessionStorage.getItem(r.name));default:return n(r.name)}},s=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n.remove(r.name,r.options);case"localstorage":return localStorage.removeItem(r.name);case"sessionstorage":return sessionStorage.removeItem(r.name);default:return n.remove(r.name,r.options)}};return new o},this.$get.$inject=["ipCookie"]}var i=e.module("angular-oauth2",["ipCookie"]).config(n).factory("oauthInterceptor",r).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$q","$rootScope","OAuthToken"],n.$inject=["$httpProvider"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file
diff --git a/src/providers/oauth-provider.js b/src/providers/oauth-provider.js
index 122f1fb..da2c5e2 100644
--- a/src/providers/oauth-provider.js
+++ b/src/providers/oauth-provider.js
@@ -167,8 +167,8 @@ function OAuthProvider() {
         };
 
         return $http.post(`${config.baseUrl}${config.grantPath}`, data, options).then((response) => {
-          
           OAuthToken.token = response.data;
+
           return response;
         });
       }
diff --git a/src/providers/oauth-token-provider.js b/src/providers/oauth-token-provider.js
index 432288d..b09b4e7 100644
--- a/src/providers/oauth-token-provider.js
+++ b/src/providers/oauth-token-provider.js
@@ -13,7 +13,7 @@ function OAuthTokenProvider() {
   var storage;
   var config = {
     name: 'token',
-    storage: 'cookies',//cookies,localStorage,sessionStorage
+    storage: 'cookies', //cookies,localStorage,sessionStorage
     options: {
       secure: true
     }
@@ -114,15 +114,16 @@ function OAuthTokenProvider() {
      * @param data
      * @returns {*}
      */
+
     var setToken = function(data) {
      storage = config.storage.toLowerCase();
       switch (storage) {
        case 'cookies':
         return ipCookie(config.name, data, config.options);
        case 'localstorage':
-        return localStorage.setItem(config.name,JSON.stringify(data));
+        return localStorage.setItem(config.name, angular.toJson(data));
        case 'sessionstorage':
-        return sessionStorage.setItem(config.name,JSON.stringify(data));
+        return localStorage.setItem(config.name, angular.toJson(data));
        default :
         return ipCookie(config.name, data, config.options);
       }
@@ -139,12 +140,11 @@ function OAuthTokenProvider() {
        case 'cookies':
         return ipCookie(config.name);
        case 'localstorage':
-        return JSON.parse(localStorage.getItem(config.name));
+        return angular.fromJson(localStorage.getItem(config.name));
        case 'sessionstorage':
-        return JSON.parse(sessionStorage.getItem(config.name));
+        return angular.fromJson(sessionStorage.getItem(config.name));
        default :
         return ipCookie(config.name);
-
       }
     };
 

From df5abac2149e8d3d2e642355dfa30a96b961155c Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Wed, 9 Sep 2015 15:19:00 -0600
Subject: [PATCH 04/11] inject $window for use with storage method

---
 README.md                             |  2 +-
 dist/angular-oauth2.js                | 20 ++++++++++----------
 dist/angular-oauth2.min.js            |  2 +-
 src/providers/oauth-token-provider.js | 10 +++++-----
 4 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/README.md b/README.md
index 2eb30b8..2fb9589 100644
--- a/README.md
+++ b/README.md
@@ -153,7 +153,7 @@ Configuration defaults:
 ```js
 OAuthTokenProvider.configure({
   name: 'token',
-  storage:'cookies' // options: 'cookies','localstorage','sessionstorage'
+  storage:'cookies' // options: 'cookies', 'localstorage', 'sessionstorage'
   options: {
     secure: true
   }
diff --git a/dist/angular-oauth2.js b/dist/angular-oauth2.js
index 5f8c90b..260f641 100644
--- a/dist/angular-oauth2.js
+++ b/dist/angular-oauth2.js
@@ -14,6 +14,10 @@
     }
 })(this, function(angular, queryString) {
     var ngModule = angular.module("angular-oauth2", [ "ipCookie" ]).config(oauthConfig).factory("oauthInterceptor", oauthInterceptor).provider("OAuth", OAuthProvider).provider("OAuthToken", OAuthTokenProvider);
+    function oauthConfig($httpProvider) {
+        $httpProvider.interceptors.push("oauthInterceptor");
+    }
+    oauthConfig.$inject = [ "$httpProvider" ];
     function oauthInterceptor($q, $rootScope, OAuthToken) {
         return {
             request: function(config) {
@@ -36,10 +40,6 @@
         };
     }
     oauthInterceptor.$inject = [ "$q", "$rootScope", "OAuthToken" ];
-    function oauthConfig($httpProvider) {
-        $httpProvider.interceptors.push("oauthInterceptor");
-    }
-    oauthConfig.$inject = [ "$httpProvider" ];
     var _prototypeProperties = function(child, staticProps, instanceProps) {
         if (staticProps) Object.defineProperties(child, staticProps);
         if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
@@ -194,7 +194,7 @@
             angular.extend(config, params);
             return config;
         };
-        this.$get = function(ipCookie) {
+        this.$get = function(ipCookie, $window) {
             var OAuthToken = function() {
                 function OAuthToken() {}
                 _prototypeProperties(OAuthToken, null, {
@@ -269,10 +269,10 @@
                     return ipCookie(config.name, data, config.options);
 
                   case "localstorage":
-                    return localStorage.setItem(config.name, angular.toJson(data));
+                    return $window.localStorage.setItem(config.name, angular.toJson(data));
 
                   case "sessionstorage":
-                    return localStorage.setItem(config.name, angular.toJson(data));
+                    return $window.sessionStorage.setItem(config.name, angular.toJson(data));
 
                   default:
                     return ipCookie(config.name, data, config.options);
@@ -285,10 +285,10 @@
                     return ipCookie(config.name);
 
                   case "localstorage":
-                    return angular.fromJson(localStorage.getItem(config.name));
+                    return angular.fromJson($window.localStorage.getItem(config.name));
 
                   case "sessionstorage":
-                    return angular.fromJson(sessionStorage.getItem(config.name));
+                    return angular.fromJson($window.sessionStorage.getItem(config.name));
 
                   default:
                     return ipCookie(config.name);
@@ -312,7 +312,7 @@
             };
             return new OAuthToken();
         };
-        this.$get.$inject = [ "ipCookie" ];
+        this.$get.$inject = [ "ipCookie", "$window" ];
     }
     return ngModule;
 });
\ No newline at end of file
diff --git a/dist/angular-oauth2.min.js b/dist/angular-oauth2.min.js
index af83d5e..d354b76 100644
--- a/dist/angular-oauth2.min.js
+++ b/dist/angular-oauth2.min.js
@@ -1 +1 @@
-!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function n(e){e.interceptors.push("oauthInterceptor")}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(n){var o=function(){function e(){}return u(e,null,{token:{set:function(e){return a(e)},get:function(){return i()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return s()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),a=function(o){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name,o,r.options);case"localstorage":return localStorage.setItem(r.name,e.toJson(o));case"sessionstorage":return localStorage.setItem(r.name,e.toJson(o));default:return n(r.name,o,r.options)}},i=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name);case"localstorage":return e.fromJson(localStorage.getItem(r.name));case"sessionstorage":return e.fromJson(sessionStorage.getItem(r.name));default:return n(r.name)}},s=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n.remove(r.name,r.options);case"localstorage":return localStorage.removeItem(r.name);case"sessionstorage":return sessionStorage.removeItem(r.name);default:return n.remove(r.name,r.options)}};return new o},this.$get.$inject=["ipCookie"]}var i=e.module("angular-oauth2",["ipCookie"]).config(n).factory("oauthInterceptor",r).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$q","$rootScope","OAuthToken"],n.$inject=["$httpProvider"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file
+!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e){e.interceptors.push("oauthInterceptor")}function n(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(n,o){var a=function(){function e(){}return u(e,null,{token:{set:function(e){return i(e)},get:function(){return s()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return c()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),i=function(a){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name,a,r.options);case"localstorage":return o.localStorage.setItem(r.name,e.toJson(a));case"sessionstorage":return o.sessionStorage.setItem(r.name,e.toJson(a));default:return n(r.name,a,r.options)}},s=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name);case"localstorage":return e.fromJson(o.localStorage.getItem(r.name));case"sessionstorage":return e.fromJson(o.sessionStorage.getItem(r.name));default:return n(r.name)}},c=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n.remove(r.name,r.options);case"localstorage":return localStorage.removeItem(r.name);case"sessionstorage":return sessionStorage.removeItem(r.name);default:return n.remove(r.name,r.options)}};return new a},this.$get.$inject=["ipCookie","$window"]}var i=e.module("angular-oauth2",["ipCookie"]).config(r).factory("oauthInterceptor",n).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$httpProvider"],n.$inject=["$q","$rootScope","OAuthToken"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file
diff --git a/src/providers/oauth-token-provider.js b/src/providers/oauth-token-provider.js
index b09b4e7..95fd3d4 100644
--- a/src/providers/oauth-token-provider.js
+++ b/src/providers/oauth-token-provider.js
@@ -43,7 +43,7 @@ function OAuthTokenProvider() {
    * @ngInject
    */
 
-  this.$get = function(ipCookie) {
+  this.$get = function(ipCookie, $window) {
     class OAuthToken {
 
       /**
@@ -121,9 +121,9 @@ function OAuthTokenProvider() {
        case 'cookies':
         return ipCookie(config.name, data, config.options);
        case 'localstorage':
-        return localStorage.setItem(config.name, angular.toJson(data));
+        return $window.localStorage.setItem(config.name, angular.toJson(data));
        case 'sessionstorage':
-        return localStorage.setItem(config.name, angular.toJson(data));
+        return $window.sessionStorage.setItem(config.name, angular.toJson(data));
        default :
         return ipCookie(config.name, data, config.options);
       }
@@ -140,9 +140,9 @@ function OAuthTokenProvider() {
        case 'cookies':
         return ipCookie(config.name);
        case 'localstorage':
-        return angular.fromJson(localStorage.getItem(config.name));
+        return angular.fromJson($window.localStorage.getItem(config.name));
        case 'sessionstorage':
-        return angular.fromJson(sessionStorage.getItem(config.name));
+        return angular.fromJson($window.sessionStorage.getItem(config.name));
        default :
         return ipCookie(config.name);
       }

From 1d5c7863b53c5be32209b679c1d0b7bb62ce3aa7 Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Wed, 9 Sep 2015 15:41:18 -0600
Subject: [PATCH 05/11] fix indentation

---
 src/providers/oauth-token-provider.js | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/providers/oauth-token-provider.js b/src/providers/oauth-token-provider.js
index 95fd3d4..b59f131 100644
--- a/src/providers/oauth-token-provider.js
+++ b/src/providers/oauth-token-provider.js
@@ -158,13 +158,12 @@ function OAuthTokenProvider() {
       switch (storage) {
        case 'cookies':
         return ipCookie.remove(config.name, config.options);
-          case 'localstorage':
-            return localStorage.removeItem(config.name);
-          case 'sessionstorage':
-            return sessionStorage.removeItem(config.name);
-          default :
-            return ipCookie.remove(config.name, config.options);
-
+       case 'localstorage':
+        return $window.localStorage.removeItem(config.name);
+       case 'sessionstorage':
+        return $window.sessionStorage.removeItem(config.name);
+       default :
+        return ipCookie.remove(config.name, config.options);
       }
     };
 

From b565d0753fa56b250c17cd4cc66ae1d687d9dc81 Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Wed, 9 Sep 2015 15:45:24 -0600
Subject: [PATCH 06/11] fix wrong indentation

---
 dist/angular-oauth2.js     | 4 ++--
 dist/angular-oauth2.min.js | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/dist/angular-oauth2.js b/dist/angular-oauth2.js
index 260f641..ee5c5c4 100644
--- a/dist/angular-oauth2.js
+++ b/dist/angular-oauth2.js
@@ -301,10 +301,10 @@
                     return ipCookie.remove(config.name, config.options);
 
                   case "localstorage":
-                    return localStorage.removeItem(config.name);
+                    return $window.localStorage.removeItem(config.name);
 
                   case "sessionstorage":
-                    return sessionStorage.removeItem(config.name);
+                    return $window.sessionStorage.removeItem(config.name);
 
                   default:
                     return ipCookie.remove(config.name, config.options);
diff --git a/dist/angular-oauth2.min.js b/dist/angular-oauth2.min.js
index d354b76..eb15959 100644
--- a/dist/angular-oauth2.min.js
+++ b/dist/angular-oauth2.min.js
@@ -1 +1 @@
-!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e){e.interceptors.push("oauthInterceptor")}function n(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(n,o){var a=function(){function e(){}return u(e,null,{token:{set:function(e){return i(e)},get:function(){return s()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return c()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),i=function(a){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name,a,r.options);case"localstorage":return o.localStorage.setItem(r.name,e.toJson(a));case"sessionstorage":return o.sessionStorage.setItem(r.name,e.toJson(a));default:return n(r.name,a,r.options)}},s=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name);case"localstorage":return e.fromJson(o.localStorage.getItem(r.name));case"sessionstorage":return e.fromJson(o.sessionStorage.getItem(r.name));default:return n(r.name)}},c=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n.remove(r.name,r.options);case"localstorage":return localStorage.removeItem(r.name);case"sessionstorage":return sessionStorage.removeItem(r.name);default:return n.remove(r.name,r.options)}};return new a},this.$get.$inject=["ipCookie","$window"]}var i=e.module("angular-oauth2",["ipCookie"]).config(r).factory("oauthInterceptor",n).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$httpProvider"],n.$inject=["$q","$rootScope","OAuthToken"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file
+!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e){e.interceptors.push("oauthInterceptor")}function n(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(n,o){var a=function(){function e(){}return u(e,null,{token:{set:function(e){return i(e)},get:function(){return s()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return c()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),i=function(a){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name,a,r.options);case"localstorage":return o.localStorage.setItem(r.name,e.toJson(a));case"sessionstorage":return o.sessionStorage.setItem(r.name,e.toJson(a));default:return n(r.name,a,r.options)}},s=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name);case"localstorage":return e.fromJson(o.localStorage.getItem(r.name));case"sessionstorage":return e.fromJson(o.sessionStorage.getItem(r.name));default:return n(r.name)}},c=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n.remove(r.name,r.options);case"localstorage":return o.localStorage.removeItem(r.name);case"sessionstorage":return o.sessionStorage.removeItem(r.name);default:return n.remove(r.name,r.options)}};return new a},this.$get.$inject=["ipCookie","$window"]}var i=e.module("angular-oauth2",["ipCookie"]).config(r).factory("oauthInterceptor",n).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$httpProvider"],n.$inject=["$q","$rootScope","OAuthToken"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file

From 14f35d35d6b55adc9e43fda8e4cc61253cf8d252 Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Wed, 9 Sep 2015 15:45:24 -0600
Subject: [PATCH 07/11] fix wrong indentation

---
 dist/angular-oauth2.js     | 4 ++--
 dist/angular-oauth2.min.js | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/dist/angular-oauth2.js b/dist/angular-oauth2.js
index 260f641..ee5c5c4 100644
--- a/dist/angular-oauth2.js
+++ b/dist/angular-oauth2.js
@@ -301,10 +301,10 @@
                     return ipCookie.remove(config.name, config.options);
 
                   case "localstorage":
-                    return localStorage.removeItem(config.name);
+                    return $window.localStorage.removeItem(config.name);
 
                   case "sessionstorage":
-                    return sessionStorage.removeItem(config.name);
+                    return $window.sessionStorage.removeItem(config.name);
 
                   default:
                     return ipCookie.remove(config.name, config.options);
diff --git a/dist/angular-oauth2.min.js b/dist/angular-oauth2.min.js
index d354b76..eb15959 100644
--- a/dist/angular-oauth2.min.js
+++ b/dist/angular-oauth2.min.js
@@ -1 +1 @@
-!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e){e.interceptors.push("oauthInterceptor")}function n(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(n,o){var a=function(){function e(){}return u(e,null,{token:{set:function(e){return i(e)},get:function(){return s()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return c()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),i=function(a){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name,a,r.options);case"localstorage":return o.localStorage.setItem(r.name,e.toJson(a));case"sessionstorage":return o.sessionStorage.setItem(r.name,e.toJson(a));default:return n(r.name,a,r.options)}},s=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name);case"localstorage":return e.fromJson(o.localStorage.getItem(r.name));case"sessionstorage":return e.fromJson(o.sessionStorage.getItem(r.name));default:return n(r.name)}},c=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n.remove(r.name,r.options);case"localstorage":return localStorage.removeItem(r.name);case"sessionstorage":return sessionStorage.removeItem(r.name);default:return n.remove(r.name,r.options)}};return new a},this.$get.$inject=["ipCookie","$window"]}var i=e.module("angular-oauth2",["ipCookie"]).config(r).factory("oauthInterceptor",n).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$httpProvider"],n.$inject=["$q","$rootScope","OAuthToken"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file
+!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e){e.interceptors.push("oauthInterceptor")}function n(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(n,o){var a=function(){function e(){}return u(e,null,{token:{set:function(e){return i(e)},get:function(){return s()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return c()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),i=function(a){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name,a,r.options);case"localstorage":return o.localStorage.setItem(r.name,e.toJson(a));case"sessionstorage":return o.sessionStorage.setItem(r.name,e.toJson(a));default:return n(r.name,a,r.options)}},s=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name);case"localstorage":return e.fromJson(o.localStorage.getItem(r.name));case"sessionstorage":return e.fromJson(o.sessionStorage.getItem(r.name));default:return n(r.name)}},c=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n.remove(r.name,r.options);case"localstorage":return o.localStorage.removeItem(r.name);case"sessionstorage":return o.sessionStorage.removeItem(r.name);default:return n.remove(r.name,r.options)}};return new a},this.$get.$inject=["ipCookie","$window"]}var i=e.module("angular-oauth2",["ipCookie"]).config(r).factory("oauthInterceptor",n).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$httpProvider"],n.$inject=["$q","$rootScope","OAuthToken"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file

From b235a0b17b9fa2c57414505600f65101527edc34 Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Fri, 18 Sep 2015 11:52:33 -0600
Subject: [PATCH 08/11] update readme. OAuthTokenProvider.configure example

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 2fb9589..9a5e89f 100644
--- a/README.md
+++ b/README.md
@@ -153,9 +153,9 @@ Configuration defaults:
 ```js
 OAuthTokenProvider.configure({
   name: 'token',
-  storage:'cookies' // options: 'cookies', 'localstorage', 'sessionstorage'
+  storage:'cookies', // options: 'cookies', 'localstorage', 'sessionstorage'
   options: {
-    secure: true
+    secure: true // optional, is valid if you're using cookies storage
   }
 });
 ```

From 9ad449197f32269ccae8e9e53ee64c74b9392c9f Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Fri, 18 Sep 2015 16:12:26 -0600
Subject: [PATCH 09/11] add oauthStorageService

---
 bower.json                             |   3 +-
 dist/angular-oauth2.js                 | 169 +++++++++++++++----------
 dist/angular-oauth2.min.js             |   2 +-
 karma.conf.js                          |   3 +-
 package.json                           |   1 +
 src/angular-oauth2.js                  |   8 +-
 src/providers/oauth-token-provider.js  |  75 ++---------
 src/services/oauth-storage-provider.js | 111 ++++++++++++++++
 test/mocks/angular-cookies.mock.js     |   2 +-
 9 files changed, 238 insertions(+), 136 deletions(-)
 create mode 100644 src/services/oauth-storage-provider.js

diff --git a/bower.json b/bower.json
index 663aa7c..6ad0aae 100644
--- a/bower.json
+++ b/bower.json
@@ -24,7 +24,8 @@
   ],
   "dependencies": {
     "angular": "^1.3.9",
-    "angular-cookie": "^4.0.6",
+    "angular-cookies": "~1.4.6",
+    "ngstorage": "~0.3.9",
     "query-string": "^1.0.0"
   }
 }
diff --git a/dist/angular-oauth2.js b/dist/angular-oauth2.js
index ee5c5c4..6170708 100644
--- a/dist/angular-oauth2.js
+++ b/dist/angular-oauth2.js
@@ -13,7 +13,7 @@
         root.angularOAuth2 = factory(root.angular, root.queryString);
     }
 })(this, function(angular, queryString) {
-    var ngModule = angular.module("angular-oauth2", [ "ipCookie" ]).config(oauthConfig).factory("oauthInterceptor", oauthInterceptor).provider("OAuth", OAuthProvider).provider("OAuthToken", OAuthTokenProvider);
+    var ngModule = angular.module("angular-oauth2", [ "ngStorage", "ngCookies" ]).config(oauthConfig).factory("oauthInterceptor", oauthInterceptor).provider("OAuth", OAuthProvider).provider("OAuthToken", OAuthTokenProvider).service("OAuthStorage", OAuthStorageProvider);
     function oauthConfig($httpProvider) {
         $httpProvider.interceptors.push("oauthInterceptor");
     }
@@ -179,7 +179,6 @@
         if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
     };
     function OAuthTokenProvider() {
-        var storage;
         var config = {
             name: "token",
             storage: "cookies",
@@ -194,16 +193,18 @@
             angular.extend(config, params);
             return config;
         };
-        this.$get = function(ipCookie, $window) {
+        this.$get = function(OAuthStorage) {
             var OAuthToken = function() {
-                function OAuthToken() {}
+                function OAuthToken() {
+                    console.log(OAuthStorage);
+                }
                 _prototypeProperties(OAuthToken, null, {
                     token: {
                         set: function(data) {
-                            return setToken(data);
+                            return OAuthStorage.setToken(data);
                         },
                         get: function() {
-                            return getToken();
+                            return OAuthStorage.getToken();
                         },
                         enumerable: true,
                         configurable: true
@@ -244,17 +245,9 @@
                         configurable: true
                     },
                     removeToken: {
-                        value: function(_removeToken) {
-                            var _removeTokenWrapper = function removeToken() {
-                                return _removeToken.apply(this, arguments);
-                            };
-                            _removeTokenWrapper.toString = function() {
-                                return _removeToken.toString();
-                            };
-                            return _removeTokenWrapper;
-                        }(function() {
-                            return removeToken();
-                        }),
+                        value: function removeToken() {
+                            return OAuthStorage.removeToken();
+                        },
                         writable: true,
                         enumerable: true,
                         configurable: true
@@ -262,57 +255,103 @@
                 });
                 return OAuthToken;
             }();
-            var setToken = function(data) {
-                storage = config.storage.toLowerCase();
-                switch (storage) {
-                  case "cookies":
-                    return ipCookie(config.name, data, config.options);
-
-                  case "localstorage":
-                    return $window.localStorage.setItem(config.name, angular.toJson(data));
-
-                  case "sessionstorage":
-                    return $window.sessionStorage.setItem(config.name, angular.toJson(data));
-
-                  default:
-                    return ipCookie(config.name, data, config.options);
+            return new OAuthToken();
+        };
+        this.$get.$inject = [ "OAuthStorage" ];
+    }
+    var _prototypeProperties = function(child, staticProps, instanceProps) {
+        if (staticProps) Object.defineProperties(child, staticProps);
+        if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
+    };
+    function OAuthStorageProvider() {
+        var config = {};
+        this.$get = [ "$localStorage", "$sessionStorage", "$cookies", "$log", function($localStorage, $sessionStorage, $cookies, $log) {
+            var storage;
+            var ngStorage = (config.storage || "cookies").toLowerCase();
+            var BrowserStorage = function() {
+                function BrowserStorage(storage, name) {
+                    this.storage = storage;
+                    this.name = name;
                 }
-            };
-            var getToken = function() {
-                storage = config.storage.toLowerCase();
-                switch (storage) {
-                  case "cookies":
-                    return ipCookie(config.name);
-
-                  case "localstorage":
-                    return angular.fromJson($window.localStorage.getItem(config.name));
-
-                  case "sessionstorage":
-                    return angular.fromJson($window.sessionStorage.getItem(config.name));
-
-                  default:
-                    return ipCookie(config.name);
+                _prototypeProperties(BrowserStorage, null, {
+                    token: {
+                        set: function(data) {
+                            return this.storage.setItem(this.name, angular.toJson(data));
+                        },
+                        get: function() {
+                            return angular.fromJson(this.storage.getItem(this.name));
+                        },
+                        enumerable: true,
+                        configurable: true
+                    },
+                    deleteToken: {
+                        value: function deleteToken() {
+                            this.storage.removeItem(this.name);
+                        },
+                        writable: true,
+                        enumerable: true,
+                        configurable: true
+                    }
+                });
+                return BrowserStorage;
+            }();
+            var CookieStorage = function() {
+                function CookieStorage($cookies, name, options) {
+                    this.$cookies = storage;
+                    this.name = name;
+                    this.options = options;
                 }
-            };
-            var removeToken = function() {
-                storage = config.storage.toLowerCase();
-                switch (storage) {
-                  case "cookies":
-                    return ipCookie.remove(config.name, config.options);
-
-                  case "localstorage":
-                    return $window.localStorage.removeItem(config.name);
-
-                  case "sessionstorage":
-                    return $window.sessionStorage.removeItem(config.name);
-
-                  default:
-                    return ipCookie.remove(config.name, config.options);
+                _prototypeProperties(CookieStorage, null, {
+                    token: {
+                        set: function(value) {
+                            return this.$cookies.putObject(this.name, value, this.options);
+                        },
+                        get: function() {
+                            return this.$cookies.getObject(this.name);
+                        },
+                        enumerable: true,
+                        configurable: true
+                    },
+                    deleteToken: {
+                        value: function deleteToken() {
+                            return this.$cookies.remove(this.name, this.options);
+                        },
+                        writable: true,
+                        enumerable: true,
+                        configurable: true
+                    }
+                });
+                return CookieStorage;
+            }();
+            var OAuthStorage = function() {
+                function OAuthStorage() {
+                    this.storage = ngStorage === "cookies" ? new CookieStorage(storage, config.name, config.options) : new BrowserStorage(storage, config.name);
+                    $log.info("Storage Started");
                 }
-            };
-            return new OAuthToken();
-        };
-        this.$get.$inject = [ "ipCookie", "$window" ];
+                _prototypeProperties(OAuthStorage, null, {
+                    token: {
+                        set: function(value) {
+                            return this.storage.setToken(value);
+                        },
+                        get: function() {
+                            return this.storage.getToken();
+                        },
+                        enumerable: true,
+                        configurable: true
+                    },
+                    deleteToken: {
+                        value: function deleteToken() {
+                            return this.storage.deleteToken();
+                        },
+                        writable: true,
+                        enumerable: true,
+                        configurable: true
+                    }
+                });
+                return OAuthStorage;
+            }();
+            return new OAuthStorage();
+        } ];
     }
     return ngModule;
 });
\ No newline at end of file
diff --git a/dist/angular-oauth2.min.js b/dist/angular-oauth2.min.js
index eb15959..ee4ee3f 100644
--- a/dist/angular-oauth2.min.js
+++ b/dist/angular-oauth2.min.js
@@ -1 +1 @@
-!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function r(e){e.interceptors.push("oauthInterceptor")}function n(e,t,r){return{request:function(e){return r.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=r.getAuthorizationHeader()),e},responseError:function(n){return 400!==n.status||!n.data||"invalid_request"!==n.data.error&&"invalid_grant"!==n.data.error||(r.removeToken(),t.$emit("oauth:error",n)),401===n.status&&n.data&&"invalid_token"===n.data.error&&t.$emit("oauth:error",n),e.reject(n)}}}function o(){var r;this.configure=function(t){if(r)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return r=e.extend({},s,t),e.forEach(c,function(e){if(!r[e])throw new Error("Missing parameter: "+e+".")}),"/"===r.baseUrl.substr(-1)&&(r.baseUrl=r.baseUrl.slice(0,-1)),"/"!==r.grantPath[0]&&(r.grantPath="/"+r.grantPath),"/"!==r.revokePath[0]&&(r.revokePath="/"+r.revokePath),r},this.$get=function(n,o){var a=function(){function a(){if(!r)throw new Error("`OAuthProvider` must be configured first.")}return u(a,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(a,i){if(!a||!a.username||!a.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:r.clientId,grant_type:"password",username:a.username,password:a.password};return null!==r.clientSecret&&(u.client_secret=r.clientSecret),u=t.stringify(u),i=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},i),n.post(""+r.baseUrl+r.grantPath,u,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:r.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==r.clientSecret&&(e.client_secret=r.clientSecret),e=t.stringify(e);var a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.grantPath,e,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),a={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return n.post(""+r.baseUrl+r.revokePath,e,a).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),a}();return new a},this.$get.$inject=["$http","OAuthToken"]}function a(){var t,r={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(t){if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(r,t),r},this.$get=function(n,o){var a=function(){function e(){}return u(e,null,{token:{set:function(e){return i(e)},get:function(){return s()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(e){var t=function(){return e.apply(this,arguments)};return t.toString=function(){return e.toString()},t}(function(){return c()}),writable:!0,enumerable:!0,configurable:!0}}),e}(),i=function(a){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name,a,r.options);case"localstorage":return o.localStorage.setItem(r.name,e.toJson(a));case"sessionstorage":return o.sessionStorage.setItem(r.name,e.toJson(a));default:return n(r.name,a,r.options)}},s=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n(r.name);case"localstorage":return e.fromJson(o.localStorage.getItem(r.name));case"sessionstorage":return e.fromJson(o.sessionStorage.getItem(r.name));default:return n(r.name)}},c=function(){switch(t=r.storage.toLowerCase()){case"cookies":return n.remove(r.name,r.options);case"localstorage":return o.localStorage.removeItem(r.name);case"sessionstorage":return o.sessionStorage.removeItem(r.name);default:return n.remove(r.name,r.options)}};return new a},this.$get.$inject=["ipCookie","$window"]}var i=e.module("angular-oauth2",["ipCookie"]).config(r).factory("oauthInterceptor",n).provider("OAuth",o).provider("OAuthToken",a);r.$inject=["$httpProvider"],n.$inject=["$q","$rootScope","OAuthToken"];var u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},s={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},c=["baseUrl","clientId","grantPath","revokePath"],u=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)};return i});
\ No newline at end of file
+!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function n(e){e.interceptors.push("oauthInterceptor")}function r(e,t,n){return{request:function(e){return n.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=n.getAuthorizationHeader()),e},responseError:function(r){return 400!==r.status||!r.data||"invalid_request"!==r.data.error&&"invalid_grant"!==r.data.error||(n.removeToken(),t.$emit("oauth:error",r)),401===r.status&&r.data&&"invalid_token"===r.data.error&&t.$emit("oauth:error",r),e.reject(r)}}}function o(){var n;this.configure=function(t){if(n)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return n=e.extend({},c,t),e.forEach(l,function(e){if(!n[e])throw new Error("Missing parameter: "+e+".")}),"/"===n.baseUrl.substr(-1)&&(n.baseUrl=n.baseUrl.slice(0,-1)),"/"!==n.grantPath[0]&&(n.grantPath="/"+n.grantPath),"/"!==n.revokePath[0]&&(n.revokePath="/"+n.revokePath),n},this.$get=function(r,o){var i=function(){function i(){if(!n)throw new Error("`OAuthProvider` must be configured first.")}return s(i,null,{isAuthenticated:{value:function(){return!!o.token},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(i,a){if(!i||!i.username||!i.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:n.clientId,grant_type:"password",username:i.username,password:i.password};return null!==n.clientSecret&&(u.client_secret=n.clientSecret),u=t.stringify(u),a=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},a),r.post(""+n.baseUrl+n.grantPath,u,a).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:n.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==n.clientSecret&&(e.client_secret=n.clientSecret),e=t.stringify(e);var i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.grantPath,e,i).then(function(e){return o.token=e.data,e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.revokePath,e,i).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),i}();return new i},this.$get.$inject=["$http","OAuthToken"]}function i(){var t={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(n){if(!(n instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(t,n),t},this.$get=function(e){var t=function(){function t(){console.log(e)}return s(t,null,{token:{set:function(t){return e.setToken(t)},get:function(){return e.getToken()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.token?this.token.access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.token?this.token.refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.token?this.token.token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(){return e.removeToken()},writable:!0,enumerable:!0,configurable:!0}}),t}();return new t},this.$get.$inject=["OAuthStorage"]}function a(){var t={};this.$get=["$localStorage","$sessionStorage","$cookies","$log",function(n,r,o,i){var a,u=(t.storage||"cookies").toLowerCase(),c=function(){function t(e,t){this.storage=e,this.name=t}return s(t,null,{token:{set:function(t){return this.storage.setItem(this.name,e.toJson(t))},get:function(){return e.fromJson(this.storage.getItem(this.name))},enumerable:!0,configurable:!0},deleteToken:{value:function(){this.storage.removeItem(this.name)},writable:!0,enumerable:!0,configurable:!0}}),t}(),l=function(){function e(e,t,n){this.$cookies=a,this.name=t,this.options=n}return s(e,null,{token:{set:function(e){return this.$cookies.putObject(this.name,e,this.options)},get:function(){return this.$cookies.getObject(this.name)},enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.$cookies.remove(this.name,this.options)},writable:!0,enumerable:!0,configurable:!0}}),e}(),f=function(){function e(){this.storage="cookies"===u?new l(a,t.name,t.options):new c(a,t.name),i.info("Storage Started")}return s(e,null,{token:{set:function(e){return this.storage.setToken(e)},get:function(){return this.storage.getToken()},enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.storage.deleteToken()},writable:!0,enumerable:!0,configurable:!0}}),e}();return new f}]}var u=e.module("angular-oauth2",["ngStorage","ngCookies"]).config(n).factory("oauthInterceptor",r).provider("OAuth",o).provider("OAuthToken",i).service("OAuthStorage",a);n.$inject=["$httpProvider"],r.$inject=["$q","$rootScope","OAuthToken"];var s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},c={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},l=["baseUrl","clientId","grantPath","revokePath"],s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)};return u});
\ No newline at end of file
diff --git a/karma.conf.js b/karma.conf.js
index 463d02a..6a9fd6b 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -9,7 +9,8 @@ module.exports = function(config) {
     browsers: ['Chrome'],
     files: [
       'bower_components/angular/angular.js',
-      'bower_components/angular-cookie/angular-cookie.js',
+      'bower_components/angular-cookies/angular-cookies.js',
+      'bower_components/ngstorage/ngStorage.js',
       'bower_components/query-string/query-string.js',
       'node_modules/lodash/dist/lodash.js',
       'node_modules/angular-mocks/angular-mocks.js',
diff --git a/package.json b/package.json
index 2086f5c..114b563 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
   },
   "browser": {
     "angular": "./bower_components/angular/angular.js",
+    "ngstorage": "./bower_components/ngstorage/ngStorage.js",
     "angular-cookie": "./bower_components/angular-cookie/angular-cookie.js",
     "query-string": "./bower_components/query-string/query-string.js"
   },
diff --git a/src/angular-oauth2.js b/src/angular-oauth2.js
index a7ad359..73fede4 100644
--- a/src/angular-oauth2.js
+++ b/src/angular-oauth2.js
@@ -8,15 +8,19 @@ import OAuthProvider from './providers/oauth-provider';
 import OAuthTokenProvider from './providers/oauth-token-provider';
 import oauthConfig from './config/oauth-config';
 import oauthInterceptor from './interceptors/oauth-interceptor';
-import 'angular-cookie';
+import OAuthStorageProvider from './services/oauth-storage-provider';
+import 'ngstorage';
+import 'angular-cookies';
 
 var ngModule = angular.module('angular-oauth2', [
-    'ipCookie'
+    'ngStorage',
+    'ngCookies'
   ])
   .config(oauthConfig)
   .factory('oauthInterceptor', oauthInterceptor)
   .provider('OAuth', OAuthProvider)
   .provider('OAuthToken', OAuthTokenProvider)
+  .service('OAuthStorage', OAuthStorageProvider)
 ;
 
 /**
diff --git a/src/providers/oauth-token-provider.js b/src/providers/oauth-token-provider.js
index b59f131..eed8b5b 100644
--- a/src/providers/oauth-token-provider.js
+++ b/src/providers/oauth-token-provider.js
@@ -10,10 +10,9 @@ import angular from 'angular';
  */
 
 function OAuthTokenProvider() {
-  var storage;
   var config = {
     name: 'token',
-    storage: 'cookies', //cookies,localStorage,sessionStorage
+    storage: 'cookies', //cookies, localStorage, sessionStorage
     options: {
       secure: true
     }
@@ -43,15 +42,20 @@ function OAuthTokenProvider() {
    * @ngInject
    */
 
-  this.$get = function(ipCookie, $window) {
+  this.$get = function(OAuthStorage) {
     class OAuthToken {
 
+      constructor(){
+        console.log(OAuthStorage);
+        //OAuthStorage.configure(config);
+      }
+
       /**
        * Set token.
        */
 
       set token(data) {
-        return setToken(data);
+        return OAuthStorage.setToken(data);
       }
 
       /**
@@ -59,7 +63,7 @@ function OAuthTokenProvider() {
        */
 
       get token() {
-        return getToken();
+        return OAuthStorage.getToken();
       }
 
       /**
@@ -103,70 +107,11 @@ function OAuthTokenProvider() {
        */
 
       removeToken() {
-        return removeToken();
+        return OAuthStorage.removeToken();
       }
 
     }
 
-    /**
-     * setToken
-     *
-     * @param data
-     * @returns {*}
-     */
-
-    var setToken = function(data) {
-     storage = config.storage.toLowerCase();
-      switch (storage) {
-       case 'cookies':
-        return ipCookie(config.name, data, config.options);
-       case 'localstorage':
-        return $window.localStorage.setItem(config.name, angular.toJson(data));
-       case 'sessionstorage':
-        return $window.sessionStorage.setItem(config.name, angular.toJson(data));
-       default :
-        return ipCookie(config.name, data, config.options);
-      }
-    };
-
-    /**
-     * getToken
-     *
-     * @returns {*}
-     */
-    var getToken = function() {
-     storage = config.storage.toLowerCase();
-      switch (storage) {
-       case 'cookies':
-        return ipCookie(config.name);
-       case 'localstorage':
-        return angular.fromJson($window.localStorage.getItem(config.name));
-       case 'sessionstorage':
-        return angular.fromJson($window.sessionStorage.getItem(config.name));
-       default :
-        return ipCookie(config.name);
-      }
-    };
-
-    /**
-     * removeToken
-     *
-     * @returns {*}
-     */
-    var removeToken = function() {
-     storage = config.storage.toLowerCase();
-      switch (storage) {
-       case 'cookies':
-        return ipCookie.remove(config.name, config.options);
-       case 'localstorage':
-        return $window.localStorage.removeItem(config.name);
-       case 'sessionstorage':
-        return $window.sessionStorage.removeItem(config.name);
-       default :
-        return ipCookie.remove(config.name, config.options);
-      }
-    };
-
     return new OAuthToken();
   };
 }
diff --git a/src/services/oauth-storage-provider.js b/src/services/oauth-storage-provider.js
new file mode 100644
index 0000000..97ec522
--- /dev/null
+++ b/src/services/oauth-storage-provider.js
@@ -0,0 +1,111 @@
+/**
+ * Module dependencies.
+ */
+
+import angular from 'angular';
+
+/**
+ * Storage Service.
+ */
+
+function OAuthStorageProvider() {
+
+    var config = {};
+
+    this.configure = function (params) {
+        angular.extend(config, params);
+        return config;
+    };
+
+    /**
+     * OAuthStorage Service.
+     *
+     * @ngInject
+     */
+
+    this.$get = ['$localStorage', '$sessionStorage', '$cookies', '$log', function ($localStorage, $sessionStorage, $cookies, $log) {
+        var storage;
+        var ngStorage = (config.storage || 'cookies').toLowerCase();
+        if (ngStorage === 'localstorage') {
+            storage = $localStorage;
+        }
+        else if (ngStorage === 'sessionstorage') {
+            storage = $sessionStorage;
+        }
+        else if (ngStorage === 'cookies') {
+            storage = $cookies;
+        }
+        else {
+            $log.warn('Set storage to cookies, because storage type is unknown');
+        }
+
+        class BrowserStorage {
+            constructor(storage, name) {
+                this.storage = storage;
+                this.name = name;
+            }
+
+            set token(data) {
+                return this.storage.setItem(this.name, angular.toJson(data));
+            }
+
+            get token() {
+                return angular.fromJson(this.storage.getItem(this.name));
+            }
+
+            deleteToken() {
+                this.storage.removeItem(this.name);
+            }
+        }
+
+        class CookieStorage {
+            constructor($cookies, name, options) {
+                this.$cookies = $cookies;
+                this.name = name;
+                this.options = options;
+            }
+
+            set token(value) {
+                return this.$cookies.putObject(this.name, value, this.options);
+            }
+
+            get token() {
+                return this.$cookies.getObject(this.name);
+            }
+
+            deleteToken() {
+                return this.$cookies.remove(this.name, this.options);
+            }
+        }
+
+        class OAuthStorage {
+            constructor() {
+                this.storage = ngStorage === 'cookies' ?
+                    new CookieStorage(storage, config.name, config.options) :
+                    new BrowserStorage(storage, config.name);
+                $log.info('Storage Started');
+            }
+
+            set token(value) {
+                return this.storage.setToken(value);
+            }
+
+            get token() {
+                return this.storage.getToken();
+            }
+
+            deleteToken() {
+                return this.storage.deleteToken();
+            }
+        }
+
+        return new OAuthStorage();
+    }];
+
+}
+
+/**
+ * Export `OAuthStorageProvider`.
+ */
+
+export default OAuthStorageProvider;
diff --git a/test/mocks/angular-cookies.mock.js b/test/mocks/angular-cookies.mock.js
index 62d0b3f..c12f528 100644
--- a/test/mocks/angular-cookies.mock.js
+++ b/test/mocks/angular-cookies.mock.js
@@ -4,7 +4,7 @@
  */
 
 angular.module('angular-cookies.mock', [])
-  .factory('ipCookie', function() {
+  .factory('$cookies', function() {
     return (function () {
       var cookie;
 

From 2a9404dbc34485bee6594c6376a9666d86e24143 Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Sun, 20 Sep 2015 15:16:27 -0600
Subject: [PATCH 10/11] fix OAuthStorageProvider implementation

---
 bower.json                             |  2 +-
 dist/angular-oauth2.js                 | 87 ++++++++++++++++++--------
 dist/angular-oauth2.min.js             |  2 +-
 src/angular-oauth2.js                  |  6 +-
 src/providers/oauth-token-provider.js  | 15 +++--
 src/services/oauth-storage-provider.js | 68 +++++++++++++-------
 6 files changed, 119 insertions(+), 61 deletions(-)

diff --git a/bower.json b/bower.json
index 470c2ca..07c6868 100644
--- a/bower.json
+++ b/bower.json
@@ -24,7 +24,7 @@
   ],
   "dependencies": {
     "angular": "^1.4.0",
-    "angular-cookies": "^1.4.6",
+    "angular-cookies": "~1.4.6",
     "ngstorage": "^0.3.9",
     "query-string": "^1.0.0"
   }
diff --git a/dist/angular-oauth2.js b/dist/angular-oauth2.js
index 3e99377..18669ff 100644
--- a/dist/angular-oauth2.js
+++ b/dist/angular-oauth2.js
@@ -13,7 +13,7 @@
         root.angularOAuth2 = factory(root.angular, root.queryString);
     }
 })(this, function(angular, queryString) {
-    var ngModule = angular.module("angular-oauth2", [ "ngStorage", "ngCookies" ]).config(oauthConfig).factory("oauthInterceptor", oauthInterceptor).provider("OAuth", OAuthProvider).provider("OAuthToken", OAuthTokenProvider).service("OAuthStorage", OAuthStorageProvider);
+    var ngModule = angular.module("angular-oauth2", [ "ngCookies", "ngStorage" ]).config(oauthConfig).factory("oauthInterceptor", oauthInterceptor).provider("OAuth", OAuthProvider).provider("OAuthToken", OAuthTokenProvider).provider("OAuthStorage", OAuthStorageProvider);
     function oauthConfig($httpProvider) {
         $httpProvider.interceptors.push("oauthInterceptor");
     }
@@ -178,7 +178,7 @@
         if (staticProps) Object.defineProperties(child, staticProps);
         if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
     };
-    function OAuthTokenProvider() {
+    function OAuthTokenProvider($injector) {
         var config = {
             name: "token",
             storage: "cookies",
@@ -191,21 +191,28 @@
                 throw new TypeError("Invalid argument: `config` must be an `Object`.");
             }
             angular.extend(config, params);
+            $injector.invoke(function(OAuthStorageProvider) {
+                OAuthStorageProvider.configure(config);
+            });
             return config;
         };
         this.$get = function(OAuthStorage) {
             var OAuthToken = function() {
-                function OAuthToken() {
-                    console.log(OAuthStorage);
-                }
+                function OAuthToken() {}
                 _prototypeProperties(OAuthToken, null, {
-                    token: {
-                        set: function(data) {
+                    setToken: {
+                        value: function setToken(data) {
                             return OAuthStorage.setToken(data);
                         },
-                        get: function() {
+                        writable: true,
+                        enumerable: true,
+                        configurable: true
+                    },
+                    getToken: {
+                        value: function getToken() {
                             return OAuthStorage.getToken();
                         },
+                        writable: true,
                         enumerable: true,
                         configurable: true
                     },
@@ -264,14 +271,20 @@
         if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
     };
     function OAuthStorageProvider() {
-        var config = {};
+        var config = {
+            name: "token",
+            storage: "cookies",
+            options: {
+                secure: true
+            }
+        };
         this.configure = function(params) {
             angular.extend(config, params);
             return config;
         };
-        this.$get = [ "$localStorage", "$sessionStorage", "$cookies", "$log", function($localStorage, $sessionStorage, $cookies, $log) {
+        this.$get = function($localStorage, $sessionStorage, $cookies, $log) {
             var storage;
-            var ngStorage = (config.storage || "cookies").toLowerCase();
+            var ngStorage = config.storage.toLowerCase();
             if (ngStorage === "localstorage") {
                 storage = $localStorage;
             } else if (ngStorage === "sessionstorage") {
@@ -279,6 +292,7 @@
             } else if (ngStorage === "cookies") {
                 storage = $cookies;
             } else {
+                storage = $cookies;
                 $log.warn("Set storage to cookies, because storage type is unknown");
             }
             var BrowserStorage = function() {
@@ -287,13 +301,19 @@
                     this.name = name;
                 }
                 _prototypeProperties(BrowserStorage, null, {
-                    token: {
-                        set: function(data) {
-                            return this.storage.setItem(this.name, angular.toJson(data));
+                    setToken: {
+                        value: function setToken(data) {
+                            return this.storage[this.name] = angular.toJson(data);
                         },
-                        get: function() {
-                            return angular.fromJson(this.storage.getItem(this.name));
+                        writable: true,
+                        enumerable: true,
+                        configurable: true
+                    },
+                    getToken: {
+                        value: function getToken() {
+                            return angular.fromJson(this.storage[this.name]);
                         },
+                        writable: true,
                         enumerable: true,
                         configurable: true
                     },
@@ -315,13 +335,19 @@
                     this.options = options;
                 }
                 _prototypeProperties(CookieStorage, null, {
-                    token: {
-                        set: function(value) {
+                    setToken: {
+                        value: function setToken(value) {
                             return this.$cookies.putObject(this.name, value, this.options);
                         },
-                        get: function() {
+                        writable: true,
+                        enumerable: true,
+                        configurable: true
+                    },
+                    getToken: {
+                        value: function getToken() {
                             return this.$cookies.getObject(this.name);
                         },
+                        writable: true,
                         enumerable: true,
                         configurable: true
                     },
@@ -337,18 +363,23 @@
                 return CookieStorage;
             }();
             var OAuthStorage = function() {
-                function OAuthStorage() {
-                    this.storage = ngStorage === "cookies" ? new CookieStorage(storage, config.name, config.options) : new BrowserStorage(storage, config.name);
-                    $log.info("Storage Started");
+                function OAuthStorage(storage) {
+                    this.storage = storage;
                 }
                 _prototypeProperties(OAuthStorage, null, {
-                    token: {
-                        set: function(value) {
+                    setToken: {
+                        value: function setToken(value) {
                             return this.storage.setToken(value);
                         },
-                        get: function() {
+                        writable: true,
+                        enumerable: true,
+                        configurable: true
+                    },
+                    getToken: {
+                        value: function getToken() {
                             return this.storage.getToken();
                         },
+                        writable: true,
                         enumerable: true,
                         configurable: true
                     },
@@ -363,8 +394,10 @@
                 });
                 return OAuthStorage;
             }();
-            return new OAuthStorage();
-        } ];
+            storage = ngStorage === "cookies" ? new CookieStorage(storage, config.name, config.options) : new BrowserStorage(storage, config.name);
+            return new OAuthStorage(storage);
+        };
+        this.$get.$inject = [ "$localStorage", "$sessionStorage", "$cookies", "$log" ];
     }
     return ngModule;
 });
\ No newline at end of file
diff --git a/dist/angular-oauth2.min.js b/dist/angular-oauth2.min.js
index f0664d9..5dff709 100644
--- a/dist/angular-oauth2.min.js
+++ b/dist/angular-oauth2.min.js
@@ -1 +1 @@
-!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function n(e){e.interceptors.push("oauthInterceptor")}function r(e,t,n){return{request:function(e){return n.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=n.getAuthorizationHeader()),e},responseError:function(r){return 400!==r.status||!r.data||"invalid_request"!==r.data.error&&"invalid_grant"!==r.data.error||(n.removeToken(),t.$emit("oauth:error",r)),(401===r.status&&r.data&&"invalid_token"===r.data.error||r.headers("www-authenticate")&&0===r.headers("www-authenticate").indexOf("Bearer"))&&t.$emit("oauth:error",r),e.reject(r)}}}function o(){var n;this.configure=function(t){if(n)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return n=e.extend({},c,t),e.forEach(l,function(e){if(!n[e])throw new Error("Missing parameter: "+e+".")}),"/"===n.baseUrl.substr(-1)&&(n.baseUrl=n.baseUrl.slice(0,-1)),"/"!==n.grantPath[0]&&(n.grantPath="/"+n.grantPath),"/"!==n.revokePath[0]&&(n.revokePath="/"+n.revokePath),n},this.$get=function(r,o){var i=function(){function i(){if(!n)throw new Error("`OAuthProvider` must be configured first.")}return s(i,null,{isAuthenticated:{value:function(){return!!o.getToken()},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(i,a){if(!i||!i.username||!i.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:n.clientId,grant_type:"password",username:i.username,password:i.password};return null!==n.clientSecret&&(u.client_secret=n.clientSecret),u=t.stringify(u),a=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},a),r.post(""+n.baseUrl+n.grantPath,u,a).then(function(e){return o.setToken(e.data),e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:n.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==n.clientSecret&&(e.client_secret=n.clientSecret),e=t.stringify(e);var i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.grantPath,e,i).then(function(e){return o.setToken(e.data),e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.revokePath,e,i).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),i}();return new i},this.$get.$inject=["$http","OAuthToken"]}function i(){var t={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(n){if(!(n instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(t,n),t},this.$get=function(e){var t=function(){function t(){console.log(e)}return s(t,null,{token:{set:function(t){return e.setToken(t)},get:function(){return e.getToken()},enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.getToken()?this.getToken().access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.getToken()?this.getToken().refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.getToken()?this.getToken().token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(){return e.removeToken()},writable:!0,enumerable:!0,configurable:!0}}),t}();return new t},this.$get.$inject=["OAuthStorage"]}function a(){var t={};this.configure=function(n){return e.extend(t,n),t},this.$get=["$localStorage","$sessionStorage","$cookies","$log",function(n,r,o,i){var a,u=(t.storage||"cookies").toLowerCase();"localstorage"===u?a=n:"sessionstorage"===u?a=r:"cookies"===u?a=o:i.warn("Set storage to cookies, because storage type is unknown");var c=function(){function t(e,t){this.storage=e,this.name=t}return s(t,null,{token:{set:function(t){return this.storage.setItem(this.name,e.toJson(t))},get:function(){return e.fromJson(this.storage.getItem(this.name))},enumerable:!0,configurable:!0},deleteToken:{value:function(){this.storage.removeItem(this.name)},writable:!0,enumerable:!0,configurable:!0}}),t}(),l=function(){function e(e,t,n){this.$cookies=e,this.name=t,this.options=n}return s(e,null,{token:{set:function(e){return this.$cookies.putObject(this.name,e,this.options)},get:function(){return this.$cookies.getObject(this.name)},enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.$cookies.remove(this.name,this.options)},writable:!0,enumerable:!0,configurable:!0}}),e}(),f=function(){function e(){this.storage="cookies"===u?new l(a,t.name,t.options):new c(a,t.name),i.info("Storage Started")}return s(e,null,{token:{set:function(e){return this.storage.setToken(e)},get:function(){return this.storage.getToken()},enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.storage.deleteToken()},writable:!0,enumerable:!0,configurable:!0}}),e}();return new f}]}var u=e.module("angular-oauth2",["ngStorage","ngCookies"]).config(n).factory("oauthInterceptor",r).provider("OAuth",o).provider("OAuthToken",i).service("OAuthStorage",a);n.$inject=["$httpProvider"],r.$inject=["$q","$rootScope","OAuthToken"];var s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},c={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},l=["baseUrl","clientId","grantPath","revokePath"],s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)};return u});
\ No newline at end of file
+!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function n(e){e.interceptors.push("oauthInterceptor")}function r(e,t,n){return{request:function(e){return n.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=n.getAuthorizationHeader()),e},responseError:function(r){return 400!==r.status||!r.data||"invalid_request"!==r.data.error&&"invalid_grant"!==r.data.error||(n.removeToken(),t.$emit("oauth:error",r)),(401===r.status&&r.data&&"invalid_token"===r.data.error||r.headers("www-authenticate")&&0===r.headers("www-authenticate").indexOf("Bearer"))&&t.$emit("oauth:error",r),e.reject(r)}}}function o(){var n;this.configure=function(t){if(n)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return n=e.extend({},c,t),e.forEach(l,function(e){if(!n[e])throw new Error("Missing parameter: "+e+".")}),"/"===n.baseUrl.substr(-1)&&(n.baseUrl=n.baseUrl.slice(0,-1)),"/"!==n.grantPath[0]&&(n.grantPath="/"+n.grantPath),"/"!==n.revokePath[0]&&(n.revokePath="/"+n.revokePath),n},this.$get=function(r,o){var i=function(){function i(){if(!n)throw new Error("`OAuthProvider` must be configured first.")}return s(i,null,{isAuthenticated:{value:function(){return!!o.getToken()},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(i,a){if(!i||!i.username||!i.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:n.clientId,grant_type:"password",username:i.username,password:i.password};return null!==n.clientSecret&&(u.client_secret=n.clientSecret),u=t.stringify(u),a=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},a),r.post(""+n.baseUrl+n.grantPath,u,a).then(function(e){return o.setToken(e.data),e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:n.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==n.clientSecret&&(e.client_secret=n.clientSecret),e=t.stringify(e);var i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.grantPath,e,i).then(function(e){return o.setToken(e.data),e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.revokePath,e,i).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),i}();return new i},this.$get.$inject=["$http","OAuthToken"]}function i(t){var n={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(r){if(!(r instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(n,r),t.invoke(function(e){e.configure(n)}),n},this.$get=function(e){var t=function(){function t(){}return s(t,null,{setToken:{value:function(t){return e.setToken(t)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return e.getToken()},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.getToken()?this.getToken().access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.getToken()?this.getToken().refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.getToken()?this.getToken().token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(){return e.removeToken()},writable:!0,enumerable:!0,configurable:!0}}),t}();return new t},this.$get.$inject=["OAuthStorage"]}function a(){var t={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(n){return e.extend(t,n),t},this.$get=function(n,r,o,i){var a,u=t.storage.toLowerCase();"localstorage"===u?a=n:"sessionstorage"===u?a=r:"cookies"===u?a=o:(a=o,i.warn("Set storage to cookies, because storage type is unknown"));var c=function(){function t(e,t){this.storage=e,this.name=t}return s(t,null,{setToken:{value:function(t){return this.storage[this.name]=e.toJson(t)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return e.fromJson(this.storage[this.name])},writable:!0,enumerable:!0,configurable:!0},deleteToken:{value:function(){this.storage.removeItem(this.name)},writable:!0,enumerable:!0,configurable:!0}}),t}(),l=function(){function e(e,t,n){this.$cookies=e,this.name=t,this.options=n}return s(e,null,{setToken:{value:function(e){return this.$cookies.putObject(this.name,e,this.options)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return this.$cookies.getObject(this.name)},writable:!0,enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.$cookies.remove(this.name,this.options)},writable:!0,enumerable:!0,configurable:!0}}),e}(),f=function(){function e(e){this.storage=e}return s(e,null,{setToken:{value:function(e){return this.storage.setToken(e)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return this.storage.getToken()},writable:!0,enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.storage.deleteToken()},writable:!0,enumerable:!0,configurable:!0}}),e}();return a="cookies"===u?new l(a,t.name,t.options):new c(a,t.name),new f(a)},this.$get.$inject=["$localStorage","$sessionStorage","$cookies","$log"]}var u=e.module("angular-oauth2",["ngCookies","ngStorage"]).config(n).factory("oauthInterceptor",r).provider("OAuth",o).provider("OAuthToken",i).provider("OAuthStorage",a);n.$inject=["$httpProvider"],r.$inject=["$q","$rootScope","OAuthToken"];var s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},c={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},l=["baseUrl","clientId","grantPath","revokePath"],s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)};return u});
\ No newline at end of file
diff --git a/src/angular-oauth2.js b/src/angular-oauth2.js
index 526da10..3de1526 100644
--- a/src/angular-oauth2.js
+++ b/src/angular-oauth2.js
@@ -13,14 +13,14 @@ import 'angular-cookies';
 import 'ngstorage';
 
 var ngModule = angular.module('angular-oauth2', [
-    'ngStorage',
-    'ngCookies'
+    'ngCookies',
+    'ngStorage'
   ])
   .config(oauthConfig)
   .factory('oauthInterceptor', oauthInterceptor)
   .provider('OAuth', OAuthProvider)
   .provider('OAuthToken', OAuthTokenProvider)
-  .service('OAuthStorage', OAuthStorageProvider)
+  .provider('OAuthStorage', OAuthStorageProvider)
 ;
 
 /**
diff --git a/src/providers/oauth-token-provider.js b/src/providers/oauth-token-provider.js
index fd467dc..40560f0 100644
--- a/src/providers/oauth-token-provider.js
+++ b/src/providers/oauth-token-provider.js
@@ -9,7 +9,7 @@ import angular from 'angular';
  * Token provider.
  */
 
-function OAuthTokenProvider() {
+function OAuthTokenProvider($injector) {
   var config = {
     name: 'token',
     storage: 'cookies', //cookies, localStorage, sessionStorage
@@ -33,6 +33,10 @@ function OAuthTokenProvider() {
     // Extend default configuration.
     angular.extend(config, params);
 
+    $injector.invoke(function (OAuthStorageProvider) {
+      OAuthStorageProvider.configure(config);
+    });
+
     return config;
   };
 
@@ -45,16 +49,11 @@ function OAuthTokenProvider() {
   this.$get = function(OAuthStorage) {
     class OAuthToken {
 
-      constructor(){
-        console.log(OAuthStorage);
-        //OAuthStorage.configure(config);
-      }
-
       /**
        * Set token.
        */
 
-      set token(data) {
+      setToken(data) {
         return OAuthStorage.setToken(data);
       }
 
@@ -62,7 +61,7 @@ function OAuthTokenProvider() {
        * Get token.
        */
 
-      get token() {
+      getToken() {
         return OAuthStorage.getToken();
       }
 
diff --git a/src/services/oauth-storage-provider.js b/src/services/oauth-storage-provider.js
index 97ec522..33a26fe 100644
--- a/src/services/oauth-storage-provider.js
+++ b/src/services/oauth-storage-provider.js
@@ -5,14 +5,27 @@
 import angular from 'angular';
 
 /**
- * Storage Service.
+ * OAuthStorage Service.
  */
 
 function OAuthStorageProvider() {
 
-    var config = {};
+    var config = {
+        name: 'token',
+        storage: 'cookies', //cookies, localStorage, sessionStorage
+        options: {
+            secure: true
+        }
+    };
+
+    /**
+     * Configure.
+     *
+     * @param {object} params - An `object` of params to extend.
+     */
 
-    this.configure = function (params) {
+    this.configure = function(params) {
+        // Extend default configuration.
         angular.extend(config, params);
         return config;
     };
@@ -23,9 +36,9 @@ function OAuthStorageProvider() {
      * @ngInject
      */
 
-    this.$get = ['$localStorage', '$sessionStorage', '$cookies', '$log', function ($localStorage, $sessionStorage, $cookies, $log) {
+    this.$get = function ($localStorage, $sessionStorage, $cookies, $log) {
         var storage;
-        var ngStorage = (config.storage || 'cookies').toLowerCase();
+        var ngStorage = config.storage.toLowerCase();
         if (ngStorage === 'localstorage') {
             storage = $localStorage;
         }
@@ -36,6 +49,7 @@ function OAuthStorageProvider() {
             storage = $cookies;
         }
         else {
+            storage = $cookies;
             $log.warn('Set storage to cookies, because storage type is unknown');
         }
 
@@ -45,12 +59,12 @@ function OAuthStorageProvider() {
                 this.name = name;
             }
 
-            set token(data) {
-                return this.storage.setItem(this.name, angular.toJson(data));
+            setToken(data) {
+                return (this.storage[this.name] = angular.toJson(data));
             }
 
-            get token() {
-                return angular.fromJson(this.storage.getItem(this.name));
+            getToken() {
+                return angular.fromJson(this.storage[this.name]);
             }
 
             deleteToken() {
@@ -65,11 +79,11 @@ function OAuthStorageProvider() {
                 this.options = options;
             }
 
-            set token(value) {
+            setToken(value) {
                 return this.$cookies.putObject(this.name, value, this.options);
             }
 
-            get token() {
+            getToken() {
                 return this.$cookies.getObject(this.name);
             }
 
@@ -78,19 +92,27 @@ function OAuthStorageProvider() {
             }
         }
 
-        class OAuthStorage {
-            constructor() {
-                this.storage = ngStorage === 'cookies' ?
-                    new CookieStorage(storage, config.name, config.options) :
-                    new BrowserStorage(storage, config.name);
-                $log.info('Storage Started');
+
+        class  OAuthStorage {
+            constructor(storage) {
+                this.storage = storage;
             }
 
-            set token(value) {
+            /**
+             * setToken
+             *
+             * @param value
+             * @returns {*}
+             */
+            setToken(value) {
                 return this.storage.setToken(value);
             }
 
-            get token() {
+            /**
+             * getToken
+             * @returns {*}
+             */
+            getToken() {
                 return this.storage.getToken();
             }
 
@@ -99,8 +121,12 @@ function OAuthStorageProvider() {
             }
         }
 
-        return new OAuthStorage();
-    }];
+        storage = ngStorage === 'cookies' ?
+            new CookieStorage(storage, config.name, config.options) :
+            new BrowserStorage(storage, config.name);
+
+        return new OAuthStorage(storage);
+    };
 
 }
 

From f152d5705d7bbfe1c0501ca906ff1dea3e3e40cb Mon Sep 17 00:00:00 2001
From: Jarbit Lira <jarbitlira@gmail.com>
Date: Sun, 20 Sep 2015 22:29:40 -0600
Subject: [PATCH 11/11] fix removeToken method OAuthStorage

---
 dist/angular-oauth2.js                 | 4 ++--
 dist/angular-oauth2.min.js             | 2 +-
 src/providers/oauth-token-provider.js  | 2 +-
 src/services/oauth-storage-provider.js | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/dist/angular-oauth2.js b/dist/angular-oauth2.js
index 18669ff..1da5dff 100644
--- a/dist/angular-oauth2.js
+++ b/dist/angular-oauth2.js
@@ -253,7 +253,7 @@
                     },
                     removeToken: {
                         value: function removeToken() {
-                            return OAuthStorage.removeToken();
+                            return OAuthStorage.deleteToken();
                         },
                         writable: true,
                         enumerable: true,
@@ -319,7 +319,7 @@
                     },
                     deleteToken: {
                         value: function deleteToken() {
-                            this.storage.removeItem(this.name);
+                            delete this.storage[this.name];
                         },
                         writable: true,
                         enumerable: true,
diff --git a/dist/angular-oauth2.min.js b/dist/angular-oauth2.min.js
index 5dff709..7484934 100644
--- a/dist/angular-oauth2.min.js
+++ b/dist/angular-oauth2.min.js
@@ -1 +1 @@
-!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function n(e){e.interceptors.push("oauthInterceptor")}function r(e,t,n){return{request:function(e){return n.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=n.getAuthorizationHeader()),e},responseError:function(r){return 400!==r.status||!r.data||"invalid_request"!==r.data.error&&"invalid_grant"!==r.data.error||(n.removeToken(),t.$emit("oauth:error",r)),(401===r.status&&r.data&&"invalid_token"===r.data.error||r.headers("www-authenticate")&&0===r.headers("www-authenticate").indexOf("Bearer"))&&t.$emit("oauth:error",r),e.reject(r)}}}function o(){var n;this.configure=function(t){if(n)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return n=e.extend({},c,t),e.forEach(l,function(e){if(!n[e])throw new Error("Missing parameter: "+e+".")}),"/"===n.baseUrl.substr(-1)&&(n.baseUrl=n.baseUrl.slice(0,-1)),"/"!==n.grantPath[0]&&(n.grantPath="/"+n.grantPath),"/"!==n.revokePath[0]&&(n.revokePath="/"+n.revokePath),n},this.$get=function(r,o){var i=function(){function i(){if(!n)throw new Error("`OAuthProvider` must be configured first.")}return s(i,null,{isAuthenticated:{value:function(){return!!o.getToken()},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(i,a){if(!i||!i.username||!i.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:n.clientId,grant_type:"password",username:i.username,password:i.password};return null!==n.clientSecret&&(u.client_secret=n.clientSecret),u=t.stringify(u),a=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},a),r.post(""+n.baseUrl+n.grantPath,u,a).then(function(e){return o.setToken(e.data),e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:n.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==n.clientSecret&&(e.client_secret=n.clientSecret),e=t.stringify(e);var i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.grantPath,e,i).then(function(e){return o.setToken(e.data),e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.revokePath,e,i).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),i}();return new i},this.$get.$inject=["$http","OAuthToken"]}function i(t){var n={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(r){if(!(r instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(n,r),t.invoke(function(e){e.configure(n)}),n},this.$get=function(e){var t=function(){function t(){}return s(t,null,{setToken:{value:function(t){return e.setToken(t)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return e.getToken()},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.getToken()?this.getToken().access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.getToken()?this.getToken().refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.getToken()?this.getToken().token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(){return e.removeToken()},writable:!0,enumerable:!0,configurable:!0}}),t}();return new t},this.$get.$inject=["OAuthStorage"]}function a(){var t={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(n){return e.extend(t,n),t},this.$get=function(n,r,o,i){var a,u=t.storage.toLowerCase();"localstorage"===u?a=n:"sessionstorage"===u?a=r:"cookies"===u?a=o:(a=o,i.warn("Set storage to cookies, because storage type is unknown"));var c=function(){function t(e,t){this.storage=e,this.name=t}return s(t,null,{setToken:{value:function(t){return this.storage[this.name]=e.toJson(t)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return e.fromJson(this.storage[this.name])},writable:!0,enumerable:!0,configurable:!0},deleteToken:{value:function(){this.storage.removeItem(this.name)},writable:!0,enumerable:!0,configurable:!0}}),t}(),l=function(){function e(e,t,n){this.$cookies=e,this.name=t,this.options=n}return s(e,null,{setToken:{value:function(e){return this.$cookies.putObject(this.name,e,this.options)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return this.$cookies.getObject(this.name)},writable:!0,enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.$cookies.remove(this.name,this.options)},writable:!0,enumerable:!0,configurable:!0}}),e}(),f=function(){function e(e){this.storage=e}return s(e,null,{setToken:{value:function(e){return this.storage.setToken(e)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return this.storage.getToken()},writable:!0,enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.storage.deleteToken()},writable:!0,enumerable:!0,configurable:!0}}),e}();return a="cookies"===u?new l(a,t.name,t.options):new c(a,t.name),new f(a)},this.$get.$inject=["$localStorage","$sessionStorage","$cookies","$log"]}var u=e.module("angular-oauth2",["ngCookies","ngStorage"]).config(n).factory("oauthInterceptor",r).provider("OAuth",o).provider("OAuthToken",i).provider("OAuthStorage",a);n.$inject=["$httpProvider"],r.$inject=["$q","$rootScope","OAuthToken"];var s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},c={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},l=["baseUrl","clientId","grantPath","revokePath"],s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)};return u});
\ No newline at end of file
+!function(e,t){"function"==typeof define&&define.amd?define(["angular","query-string"],t):"object"==typeof exports?module.exports=t(require("angular"),require("query-string")):e.angularOAuth2=t(e.angular,e.queryString)}(this,function(e,t){function n(e){e.interceptors.push("oauthInterceptor")}function r(e,t,n){return{request:function(e){return n.getAuthorizationHeader()&&(e.headers=e.headers||{},e.headers.Authorization=n.getAuthorizationHeader()),e},responseError:function(r){return 400!==r.status||!r.data||"invalid_request"!==r.data.error&&"invalid_grant"!==r.data.error||(n.removeToken(),t.$emit("oauth:error",r)),(401===r.status&&r.data&&"invalid_token"===r.data.error||r.headers("www-authenticate")&&0===r.headers("www-authenticate").indexOf("Bearer"))&&t.$emit("oauth:error",r),e.reject(r)}}}function o(){var n;this.configure=function(t){if(n)throw new Error("Already configured.");if(!(t instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return n=e.extend({},c,t),e.forEach(l,function(e){if(!n[e])throw new Error("Missing parameter: "+e+".")}),"/"===n.baseUrl.substr(-1)&&(n.baseUrl=n.baseUrl.slice(0,-1)),"/"!==n.grantPath[0]&&(n.grantPath="/"+n.grantPath),"/"!==n.revokePath[0]&&(n.revokePath="/"+n.revokePath),n},this.$get=function(r,o){var i=function(){function i(){if(!n)throw new Error("`OAuthProvider` must be configured first.")}return s(i,null,{isAuthenticated:{value:function(){return!!o.getToken()},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(i,a){if(!i||!i.username||!i.password)throw new Error("`user` must be an object with `username` and `password` properties.");var u={client_id:n.clientId,grant_type:"password",username:i.username,password:i.password};return null!==n.clientSecret&&(u.client_secret=n.clientSecret),u=t.stringify(u),a=e.extend({headers:{"Content-Type":"application/x-www-form-urlencoded"}},a),r.post(""+n.baseUrl+n.grantPath,u,a).then(function(e){return o.setToken(e.data),e})},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){var e={client_id:n.clientId,grant_type:"refresh_token",refresh_token:o.getRefreshToken()};null!==n.clientSecret&&(e.client_secret=n.clientSecret),e=t.stringify(e);var i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.grantPath,e,i).then(function(e){return o.setToken(e.data),e})},writable:!0,enumerable:!0,configurable:!0},revokeToken:{value:function(){var e=t.stringify({token:o.getRefreshToken()?o.getRefreshToken():o.getAccessToken()}),i={headers:{"Content-Type":"application/x-www-form-urlencoded"}};return r.post(""+n.baseUrl+n.revokePath,e,i).then(function(e){return o.removeToken(),e})},writable:!0,enumerable:!0,configurable:!0}}),i}();return new i},this.$get.$inject=["$http","OAuthToken"]}function i(t){var n={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(r){if(!(r instanceof Object))throw new TypeError("Invalid argument: `config` must be an `Object`.");return e.extend(n,r),t.invoke(function(e){e.configure(n)}),n},this.$get=function(e){var t=function(){function t(){}return s(t,null,{setToken:{value:function(t){return e.setToken(t)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return e.getToken()},writable:!0,enumerable:!0,configurable:!0},getAccessToken:{value:function(){return this.getToken()?this.getToken().access_token:void 0},writable:!0,enumerable:!0,configurable:!0},getAuthorizationHeader:{value:function(){return this.getTokenType()&&this.getAccessToken()?""+(this.getTokenType().charAt(0).toUpperCase()+this.getTokenType().substr(1))+" "+this.getAccessToken():void 0},writable:!0,enumerable:!0,configurable:!0},getRefreshToken:{value:function(){return this.getToken()?this.getToken().refresh_token:void 0},writable:!0,enumerable:!0,configurable:!0},getTokenType:{value:function(){return this.getToken()?this.getToken().token_type:void 0},writable:!0,enumerable:!0,configurable:!0},removeToken:{value:function(){return e.deleteToken()},writable:!0,enumerable:!0,configurable:!0}}),t}();return new t},this.$get.$inject=["OAuthStorage"]}function a(){var t={name:"token",storage:"cookies",options:{secure:!0}};this.configure=function(n){return e.extend(t,n),t},this.$get=function(n,r,o,i){var a,u=t.storage.toLowerCase();"localstorage"===u?a=n:"sessionstorage"===u?a=r:"cookies"===u?a=o:(a=o,i.warn("Set storage to cookies, because storage type is unknown"));var c=function(){function t(e,t){this.storage=e,this.name=t}return s(t,null,{setToken:{value:function(t){return this.storage[this.name]=e.toJson(t)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return e.fromJson(this.storage[this.name])},writable:!0,enumerable:!0,configurable:!0},deleteToken:{value:function(){delete this.storage[this.name]},writable:!0,enumerable:!0,configurable:!0}}),t}(),l=function(){function e(e,t,n){this.$cookies=e,this.name=t,this.options=n}return s(e,null,{setToken:{value:function(e){return this.$cookies.putObject(this.name,e,this.options)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return this.$cookies.getObject(this.name)},writable:!0,enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.$cookies.remove(this.name,this.options)},writable:!0,enumerable:!0,configurable:!0}}),e}(),f=function(){function e(e){this.storage=e}return s(e,null,{setToken:{value:function(e){return this.storage.setToken(e)},writable:!0,enumerable:!0,configurable:!0},getToken:{value:function(){return this.storage.getToken()},writable:!0,enumerable:!0,configurable:!0},deleteToken:{value:function(){return this.storage.deleteToken()},writable:!0,enumerable:!0,configurable:!0}}),e}();return a="cookies"===u?new l(a,t.name,t.options):new c(a,t.name),new f(a)},this.$get.$inject=["$localStorage","$sessionStorage","$cookies","$log"]}var u=e.module("angular-oauth2",["ngCookies","ngStorage"]).config(n).factory("oauthInterceptor",r).provider("OAuth",o).provider("OAuthToken",i).provider("OAuthStorage",a);n.$inject=["$httpProvider"],r.$inject=["$q","$rootScope","OAuthToken"];var s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},c={baseUrl:null,clientId:null,clientSecret:null,grantPath:"/oauth2/token",revokePath:"/oauth2/revoke"},l=["baseUrl","clientId","grantPath","revokePath"],s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)},s=function(e,t,n){t&&Object.defineProperties(e,t),n&&Object.defineProperties(e.prototype,n)};return u});
\ No newline at end of file
diff --git a/src/providers/oauth-token-provider.js b/src/providers/oauth-token-provider.js
index 40560f0..c79a9e2 100644
--- a/src/providers/oauth-token-provider.js
+++ b/src/providers/oauth-token-provider.js
@@ -106,7 +106,7 @@ function OAuthTokenProvider($injector) {
        */
 
       removeToken() {
-        return OAuthStorage.removeToken();
+        return OAuthStorage.deleteToken();
       }
     }
 
diff --git a/src/services/oauth-storage-provider.js b/src/services/oauth-storage-provider.js
index 33a26fe..7ddeffd 100644
--- a/src/services/oauth-storage-provider.js
+++ b/src/services/oauth-storage-provider.js
@@ -68,7 +68,7 @@ function OAuthStorageProvider() {
             }
 
             deleteToken() {
-                this.storage.removeItem(this.name);
+                delete this.storage[this.name];
             }
         }