From b296b5bee236ea91d2c2114537d935d7dc4b2ccd Mon Sep 17 00:00:00 2001 From: Roman Mahrer Date: Thu, 15 Dec 2016 16:27:59 +0100 Subject: [PATCH 1/4] update to angular-1.6, fixed promise from .success to .then --- app/scripts/directives/oauth.js | 334 ++++++++++++++-------------- app/scripts/services/profile.js | 46 ++-- bower.json | 60 ++--- dist/oauth-ng.js | 382 ++++++++++++++++---------------- test/spec/services/profile.js | 204 +++++++++-------- 5 files changed, 533 insertions(+), 493 deletions(-) diff --git a/app/scripts/directives/oauth.js b/app/scripts/directives/oauth.js index a5d9690..b1c7aed 100644 --- a/app/scripts/directives/oauth.js +++ b/app/scripts/directives/oauth.js @@ -3,170 +3,172 @@ var directives = angular.module('oauth.directive', []); directives.directive('oauth', [ - 'IdToken', - 'AccessToken', - 'Endpoint', - 'Profile', - 'Storage', - 'OidcConfig', - '$location', - '$rootScope', - '$compile', - '$http', - '$templateCache', - '$timeout', - function(IdToken, AccessToken, Endpoint, Profile, Storage, OidcConfig, $location, $rootScope, $compile, $http, $templateCache, $timeout) { - - var definition = { - restrict: 'AE', - replace: true, - scope: { - site: '@', // (required) set the oauth server host (e.g. http://oauth.example.com) - clientId: '@', // (required) client id - redirectUri: '@', // (required) client redirect uri - responseType: '@', // (optional) response type, defaults to token (use 'token' for implicit flow and 'code' for authorization code flow - scope: '@', // (optional) scope - profileUri: '@', // (optional) user profile uri (e.g http://example.com/me) - template: '@', // (optional) template to render (e.g views/templates/default.html) - text: '@', // (optional) login text - authorizePath: '@', // (optional) authorization url - state: '@', // (optional) An arbitrary unique string created by your app to guard against Cross-site Request Forgery - storage: '@', // (optional) Store token in 'sessionStorage' or 'localStorage', defaults to 'sessionStorage' - nonce: '@', // (optional) Send nonce on auth request - // OpenID Connect extras, more details in id-token.js: - issuer: '@', // (optional for OpenID Connect) issuer of the id_token, should match the 'iss' claim in id_token payload - subject: '@', // (optional for OpenID Connect) subject of the id_token, should match the 'sub' claim in id_token payload - pubKey: '@', // (optional for OpenID Connect) the public key(RSA public key or X509 certificate in PEM format) to verify the signature - wellKnown: '@', // (optional for OpenID Connect) whether to load public key according to .well-known/openid-configuration endpoint - logoutPath: '@', // (optional) A url to go to at logout - sessionPath: '@' // (optional) A url to use to check the validity of the current token. - } - }; - - definition.link = function postLink(scope, element) { - scope.show = 'none'; - - scope.$watch('clientId', function() { - init(); - }); - - var init = function() { - initAttributes(); // sets defaults - Storage.use(scope.storage);// set storage - compile(); // compiles the desired layout - Endpoint.set(scope); // sets the oauth authorization url - OidcConfig.load(scope) // loads OIDC configuration from .well-known/openid-configuration if necessary - .then(function() { - IdToken.set(scope); - AccessToken.set(scope); // sets the access token object (if existing, from fragment or session) - initProfile(scope); // gets the profile resource (if existing the access token) - initView(); // sets the view (logged in or out) - checkValidity(); // ensure the validity of the current token - }); - }; - - var initAttributes = function() { - scope.authorizePath = scope.authorizePath || '/oauth/authorize'; - scope.tokenPath = scope.tokenPath || '/oauth/token'; - scope.template = scope.template || 'views/templates/default.html'; - scope.responseType = scope.responseType || 'token'; - scope.text = scope.text || 'Sign In'; - scope.state = scope.state || undefined; - scope.scope = scope.scope || undefined; - scope.storage = scope.storage || 'sessionStorage'; - }; - - var compile = function() { - $http.get(scope.template, { cache: $templateCache }).success(function(html) { - element.html(html); - $compile(element.contents())(scope); - }); - }; - - var initProfile = function(scope) { - var token = AccessToken.get(); - - if (token && token.access_token && scope.profileUri) { - Profile.find(scope.profileUri).success(function(response) { - scope.profile = response; - }); - } - }; - - var initView = function () { - var token = AccessToken.get(); - - if (!token) { - return scope.login(); - } // without access token it's logged out, so we attempt to log in - if (AccessToken.expired()) { - return expired(); - } // with a token, but it's expired - if (token.access_token) { - return authorized(); - } // if there is the access token we are done - if (token.error) { - return denied(); - } // if the request has been denied we fire the denied event - }; - - scope.login = function () { - Endpoint.redirect(); - }; - - scope.logout = function () { - Endpoint.logout(); - $rootScope.$broadcast('oauth:loggedOut'); - scope.show = 'logged-out'; - }; - - scope.$on('oauth:expired',expired); - - // user is authorized - var authorized = function() { - $rootScope.$broadcast('oauth:authorized', AccessToken.get()); - scope.show = 'logged-in'; - }; - - var expired = function() { - $rootScope.$broadcast('oauth:expired'); - scope.logout(); - }; - - // set the oauth directive to the denied status - var denied = function() { - scope.show = 'denied'; - $rootScope.$broadcast('oauth:denied'); - }; - - var checkValidity = function() { - Endpoint.checkValidity().then(function() { - $rootScope.$broadcast('oauth:valid'); - }).catch(function(message){ - $rootScope.$broadcast('oauth:invalid', message); - }); - }; - - var refreshDirective = function () { - scope.$apply(); - }; - - // Updates the template at runtime - scope.$on('oauth:template:update', function(event, template) { - scope.template = template; - compile(scope); - }); - - // Hack to update the directive content on logout - scope.$on('$routeChangeSuccess', function () { - $timeout(refreshDirective); - }); - - scope.$on('$stateChangeSuccess', function () { - $timeout(refreshDirective); - }); - }; - - return definition; - } + 'IdToken', + 'AccessToken', + 'Endpoint', + 'Profile', + 'Storage', + 'OidcConfig', + '$location', + '$rootScope', + '$compile', + '$http', + '$templateCache', + '$timeout', + function(IdToken, AccessToken, Endpoint, Profile, Storage, OidcConfig, $location, $rootScope, $compile, $http, $templateCache, $timeout) { + + var definition = { + restrict: 'AE', + replace: true, + scope: { + site: '@', // (required) set the oauth server host (e.g. http://oauth.example.com) + clientId: '@', // (required) client id + redirectUri: '@', // (required) client redirect uri + responseType: '@', // (optional) response type, defaults to token (use 'token' for implicit flow and 'code' for authorization code flow + scope: '@', // (optional) scope + profileUri: '@', // (optional) user profile uri (e.g http://example.com/me) + template: '@', // (optional) template to render (e.g views/templates/default.html) + text: '@', // (optional) login text + authorizePath: '@', // (optional) authorization url + state: '@', // (optional) An arbitrary unique string created by your app to guard against Cross-site Request Forgery + storage: '@', // (optional) Store token in 'sessionStorage' or 'localStorage', defaults to 'sessionStorage' + nonce: '@', // (optional) Send nonce on auth request + // OpenID Connect extras, more details in id-token.js: + issuer: '@', // (optional for OpenID Connect) issuer of the id_token, should match the 'iss' claim in id_token payload + subject: '@', // (optional for OpenID Connect) subject of the id_token, should match the 'sub' claim in id_token payload + pubKey: '@', // (optional for OpenID Connect) the public key(RSA public key or X509 certificate in PEM format) to verify the signature + wellKnown: '@', // (optional for OpenID Connect) whether to load public key according to .well-known/openid-configuration endpoint + logoutPath: '@', // (optional) A url to go to at logout + sessionPath: '@' // (optional) A url to use to check the validity of the current token. + } + }; + + definition.link = function postLink(scope, element) { + scope.show = 'none'; + + scope.$watch('clientId', function() { + init(); + }); + + var init = function() { + initAttributes(); // sets defaults + Storage.use(scope.storage); // set storage + compile(); // compiles the desired layout + Endpoint.set(scope); // sets the oauth authorization url + OidcConfig.load(scope) // loads OIDC configuration from .well-known/openid-configuration if necessary + .then(function() { + IdToken.set(scope); + AccessToken.set(scope); // sets the access token object (if existing, from fragment or session) + initProfile(scope); // gets the profile resource (if existing the access token) + initView(); // sets the view (logged in or out) + checkValidity(); // ensure the validity of the current token + }); + }; + + var initAttributes = function() { + scope.authorizePath = scope.authorizePath || '/oauth/authorize'; + scope.tokenPath = scope.tokenPath || '/oauth/token'; + scope.template = scope.template || 'views/templates/default.html'; + scope.responseType = scope.responseType || 'token'; + scope.text = scope.text || 'Sign In'; + scope.state = scope.state || undefined; + scope.scope = scope.scope || undefined; + scope.storage = scope.storage || 'sessionStorage'; + }; + + var compile = function() { + $http.get(scope.template, { + cache: $templateCache + }).then(function(html) { + element.html(html); + $compile(element.contents())(scope); + }); + }; + + var initProfile = function(scope) { + var token = AccessToken.get(); + + if (token && token.access_token && scope.profileUri) { + Profile.find(scope.profileUri).then(function(response) { + scope.profile = response; + }); + } + }; + + var initView = function() { + var token = AccessToken.get(); + + if (!token) { + return scope.login(); + } // without access token it's logged out, so we attempt to log in + if (AccessToken.expired()) { + return expired(); + } // with a token, but it's expired + if (token.access_token) { + return authorized(); + } // if there is the access token we are done + if (token.error) { + return denied(); + } // if the request has been denied we fire the denied event + }; + + scope.login = function() { + Endpoint.redirect(); + }; + + scope.logout = function() { + Endpoint.logout(); + $rootScope.$broadcast('oauth:loggedOut'); + scope.show = 'logged-out'; + }; + + scope.$on('oauth:expired', expired); + + // user is authorized + var authorized = function() { + $rootScope.$broadcast('oauth:authorized', AccessToken.get()); + scope.show = 'logged-in'; + }; + + var expired = function() { + $rootScope.$broadcast('oauth:expired'); + scope.logout(); + }; + + // set the oauth directive to the denied status + var denied = function() { + scope.show = 'denied'; + $rootScope.$broadcast('oauth:denied'); + }; + + var checkValidity = function() { + Endpoint.checkValidity().then(function() { + $rootScope.$broadcast('oauth:valid'); + }).catch(function(message) { + $rootScope.$broadcast('oauth:invalid', message); + }); + }; + + var refreshDirective = function() { + scope.$apply(); + }; + + // Updates the template at runtime + scope.$on('oauth:template:update', function(event, template) { + scope.template = template; + compile(scope); + }); + + // Hack to update the directive content on logout + scope.$on('$routeChangeSuccess', function() { + $timeout(refreshDirective); + }); + + scope.$on('$stateChangeSuccess', function() { + $timeout(refreshDirective); + }); + }; + + return definition; + } ]); diff --git a/app/scripts/services/profile.js b/app/scripts/services/profile.js index cc8a22a..736a53e 100644 --- a/app/scripts/services/profile.js +++ b/app/scripts/services/profile.js @@ -3,30 +3,34 @@ var profileClient = angular.module('oauth.profile', []); profileClient.factory('Profile', ['$http', 'AccessToken', '$rootScope', function($http, AccessToken, $rootScope) { - var service = {}; - var profile; + var service = {}; + var profile; - service.find = function(uri) { - var promise = $http.get(uri, { headers: headers() }); - promise.success(function(response) { - profile = response; - $rootScope.$broadcast('oauth:profile', profile); - }); - return promise; - }; + service.find = function(uri) { + var promise = $http.get(uri, { + headers: headers() + }); + promise.then(function(response) { + profile = response; + $rootScope.$broadcast('oauth:profile', profile); + }); + return promise; + }; - service.get = function() { - return profile; - }; + service.get = function() { + return profile; + }; - service.set = function(resource) { - profile = resource; - return profile; - }; + service.set = function(resource) { + profile = resource; + return profile; + }; - var headers = function() { - return { Authorization: 'Bearer ' + AccessToken.get().access_token }; - }; + var headers = function() { + return { + Authorization: 'Bearer ' + AccessToken.get().access_token + }; + }; - return service; + return service; }]); diff --git a/bower.json b/bower.json index c690710..f51dde3 100644 --- a/bower.json +++ b/bower.json @@ -1,32 +1,32 @@ { - "name": "oauth-ng", - "version": "0.4.10", - "main": [ - "dist/oauth-ng.js", - "dist/views/templates/default" - ], - "ignore": [ - "app", - "test", - "bower.json", - "Gruntfile.js", - "karma.conf.js", - "package.json" - ], - "dependencies": { - "angular": "~1.3.12", - "ngstorage": "~0.3.0", - "jsrsasign": "~5.0.5" - }, - "devDependencies": { - "json3": "~3.2.4", - "es5-shim": "~2.0.8", - "timecop": "~0.1.1", - "bootstrap-sass": "~3.0.2", - "jquery": "~1.9.1", - "angular-mocks": "~1.3.12" - }, - "resolutions": { - "angular": "1.3.20" - } + "name": "oauth-ng", + "version": "0.4.10", + "main": [ + "dist/oauth-ng.js", + "dist/views/templates/default" + ], + "ignore": [ + "app", + "test", + "bower.json", + "Gruntfile.js", + "karma.conf.js", + "package.json" + ], + "dependencies": { + "angular": "~1.6.0", + "ngstorage": "~0.3.0", + "jsrsasign": "~5.0.5" + }, + "devDependencies": { + "json3": "~3.2.4", + "es5-shim": "~2.0.8", + "timecop": "~0.1.1", + "bootstrap-sass": "~3.0.2", + "jquery": "~1.9.1", + "angular-mocks": "~1.3.12" + }, + "resolutions": { + "angular": "1.6.0" + } } diff --git a/dist/oauth-ng.js b/dist/oauth-ng.js index 785f8fa..5524161 100644 --- a/dist/oauth-ng.js +++ b/dist/oauth-ng.js @@ -1,4 +1,4 @@ -/* oauth-ng - v0.4.10 - 2016-05-25 */ +/* oauth-ng - v0.4.10 - 2016-12-15 */ 'use strict'; @@ -679,32 +679,36 @@ endpointClient.factory('Endpoint', ['$rootScope', 'AccessToken', '$q', '$http', var profileClient = angular.module('oauth.profile', []); profileClient.factory('Profile', ['$http', 'AccessToken', '$rootScope', function($http, AccessToken, $rootScope) { - var service = {}; - var profile; + var service = {}; + var profile; - service.find = function(uri) { - var promise = $http.get(uri, { headers: headers() }); - promise.success(function(response) { - profile = response; - $rootScope.$broadcast('oauth:profile', profile); - }); - return promise; - }; + service.find = function(uri) { + var promise = $http.get(uri, { + headers: headers() + }); + promise.then(function(response) { + profile = response; + $rootScope.$broadcast('oauth:profile', profile); + }); + return promise; + }; - service.get = function() { - return profile; - }; + service.get = function() { + return profile; + }; - service.set = function(resource) { - profile = resource; - return profile; - }; + service.set = function(resource) { + profile = resource; + return profile; + }; - var headers = function() { - return { Authorization: 'Bearer ' + AccessToken.get().access_token }; - }; + var headers = function() { + return { + Authorization: 'Bearer ' + AccessToken.get().access_token + }; + }; - return service; + return service; }]); 'use strict'; @@ -824,170 +828,172 @@ interceptorService.factory('ExpiredInterceptor', ['Storage', '$rootScope', funct var directives = angular.module('oauth.directive', []); directives.directive('oauth', [ - 'IdToken', - 'AccessToken', - 'Endpoint', - 'Profile', - 'Storage', - 'OidcConfig', - '$location', - '$rootScope', - '$compile', - '$http', - '$templateCache', - '$timeout', - function(IdToken, AccessToken, Endpoint, Profile, Storage, OidcConfig, $location, $rootScope, $compile, $http, $templateCache, $timeout) { - - var definition = { - restrict: 'AE', - replace: true, - scope: { - site: '@', // (required) set the oauth server host (e.g. http://oauth.example.com) - clientId: '@', // (required) client id - redirectUri: '@', // (required) client redirect uri - responseType: '@', // (optional) response type, defaults to token (use 'token' for implicit flow and 'code' for authorization code flow - scope: '@', // (optional) scope - profileUri: '@', // (optional) user profile uri (e.g http://example.com/me) - template: '@', // (optional) template to render (e.g bower_components/oauth-ng/dist/views/templates/default.html) - text: '@', // (optional) login text - authorizePath: '@', // (optional) authorization url - state: '@', // (optional) An arbitrary unique string created by your app to guard against Cross-site Request Forgery - storage: '@', // (optional) Store token in 'sessionStorage' or 'localStorage', defaults to 'sessionStorage' - nonce: '@', // (optional) Send nonce on auth request - // OpenID Connect extras, more details in id-token.js: - issuer: '@', // (optional for OpenID Connect) issuer of the id_token, should match the 'iss' claim in id_token payload - subject: '@', // (optional for OpenID Connect) subject of the id_token, should match the 'sub' claim in id_token payload - pubKey: '@', // (optional for OpenID Connect) the public key(RSA public key or X509 certificate in PEM format) to verify the signature - wellKnown: '@', // (optional for OpenID Connect) whether to load public key according to .well-known/openid-configuration endpoint - logoutPath: '@', // (optional) A url to go to at logout - sessionPath: '@' // (optional) A url to use to check the validity of the current token. - } - }; - - definition.link = function postLink(scope, element) { - scope.show = 'none'; - - scope.$watch('clientId', function() { - init(); - }); - - var init = function() { - initAttributes(); // sets defaults - Storage.use(scope.storage);// set storage - compile(); // compiles the desired layout - Endpoint.set(scope); // sets the oauth authorization url - OidcConfig.load(scope) // loads OIDC configuration from .well-known/openid-configuration if necessary - .then(function() { - IdToken.set(scope); - AccessToken.set(scope); // sets the access token object (if existing, from fragment or session) - initProfile(scope); // gets the profile resource (if existing the access token) - initView(); // sets the view (logged in or out) - checkValidity(); // ensure the validity of the current token - }); - }; - - var initAttributes = function() { - scope.authorizePath = scope.authorizePath || '/oauth/authorize'; - scope.tokenPath = scope.tokenPath || '/oauth/token'; - scope.template = scope.template || 'bower_components/oauth-ng/dist/views/templates/default.html'; - scope.responseType = scope.responseType || 'token'; - scope.text = scope.text || 'Sign In'; - scope.state = scope.state || undefined; - scope.scope = scope.scope || undefined; - scope.storage = scope.storage || 'sessionStorage'; - }; - - var compile = function() { - $http.get(scope.template, { cache: $templateCache }).success(function(html) { - element.html(html); - $compile(element.contents())(scope); - }); - }; - - var initProfile = function(scope) { - var token = AccessToken.get(); - - if (token && token.access_token && scope.profileUri) { - Profile.find(scope.profileUri).success(function(response) { - scope.profile = response; - }); - } - }; - - var initView = function () { - var token = AccessToken.get(); - - if (!token) { - return scope.login(); - } // without access token it's logged out, so we attempt to log in - if (AccessToken.expired()) { - return expired(); - } // with a token, but it's expired - if (token.access_token) { - return authorized(); - } // if there is the access token we are done - if (token.error) { - return denied(); - } // if the request has been denied we fire the denied event - }; - - scope.login = function () { - Endpoint.redirect(); - }; - - scope.logout = function () { - Endpoint.logout(); - $rootScope.$broadcast('oauth:loggedOut'); - scope.show = 'logged-out'; - }; - - scope.$on('oauth:expired',expired); - - // user is authorized - var authorized = function() { - $rootScope.$broadcast('oauth:authorized', AccessToken.get()); - scope.show = 'logged-in'; - }; - - var expired = function() { - $rootScope.$broadcast('oauth:expired'); - scope.logout(); - }; - - // set the oauth directive to the denied status - var denied = function() { - scope.show = 'denied'; - $rootScope.$broadcast('oauth:denied'); - }; - - var checkValidity = function() { - Endpoint.checkValidity().then(function() { - $rootScope.$broadcast('oauth:valid'); - }).catch(function(message){ - $rootScope.$broadcast('oauth:invalid', message); - }); - }; - - var refreshDirective = function () { - scope.$apply(); - }; - - // Updates the template at runtime - scope.$on('oauth:template:update', function(event, template) { - scope.template = template; - compile(scope); - }); - - // Hack to update the directive content on logout - scope.$on('$routeChangeSuccess', function () { - $timeout(refreshDirective); - }); - - scope.$on('$stateChangeSuccess', function () { - $timeout(refreshDirective); - }); - }; - - return definition; - } + 'IdToken', + 'AccessToken', + 'Endpoint', + 'Profile', + 'Storage', + 'OidcConfig', + '$location', + '$rootScope', + '$compile', + '$http', + '$templateCache', + '$timeout', + function(IdToken, AccessToken, Endpoint, Profile, Storage, OidcConfig, $location, $rootScope, $compile, $http, $templateCache, $timeout) { + + var definition = { + restrict: 'AE', + replace: true, + scope: { + site: '@', // (required) set the oauth server host (e.g. http://oauth.example.com) + clientId: '@', // (required) client id + redirectUri: '@', // (required) client redirect uri + responseType: '@', // (optional) response type, defaults to token (use 'token' for implicit flow and 'code' for authorization code flow + scope: '@', // (optional) scope + profileUri: '@', // (optional) user profile uri (e.g http://example.com/me) + template: '@', // (optional) template to render (e.g bower_components/oauth-ng/dist/views/templates/default.html) + text: '@', // (optional) login text + authorizePath: '@', // (optional) authorization url + state: '@', // (optional) An arbitrary unique string created by your app to guard against Cross-site Request Forgery + storage: '@', // (optional) Store token in 'sessionStorage' or 'localStorage', defaults to 'sessionStorage' + nonce: '@', // (optional) Send nonce on auth request + // OpenID Connect extras, more details in id-token.js: + issuer: '@', // (optional for OpenID Connect) issuer of the id_token, should match the 'iss' claim in id_token payload + subject: '@', // (optional for OpenID Connect) subject of the id_token, should match the 'sub' claim in id_token payload + pubKey: '@', // (optional for OpenID Connect) the public key(RSA public key or X509 certificate in PEM format) to verify the signature + wellKnown: '@', // (optional for OpenID Connect) whether to load public key according to .well-known/openid-configuration endpoint + logoutPath: '@', // (optional) A url to go to at logout + sessionPath: '@' // (optional) A url to use to check the validity of the current token. + } + }; + + definition.link = function postLink(scope, element) { + scope.show = 'none'; + + scope.$watch('clientId', function() { + init(); + }); + + var init = function() { + initAttributes(); // sets defaults + Storage.use(scope.storage); // set storage + compile(); // compiles the desired layout + Endpoint.set(scope); // sets the oauth authorization url + OidcConfig.load(scope) // loads OIDC configuration from .well-known/openid-configuration if necessary + .then(function() { + IdToken.set(scope); + AccessToken.set(scope); // sets the access token object (if existing, from fragment or session) + initProfile(scope); // gets the profile resource (if existing the access token) + initView(); // sets the view (logged in or out) + checkValidity(); // ensure the validity of the current token + }); + }; + + var initAttributes = function() { + scope.authorizePath = scope.authorizePath || '/oauth/authorize'; + scope.tokenPath = scope.tokenPath || '/oauth/token'; + scope.template = scope.template || 'bower_components/oauth-ng/dist/views/templates/default.html'; + scope.responseType = scope.responseType || 'token'; + scope.text = scope.text || 'Sign In'; + scope.state = scope.state || undefined; + scope.scope = scope.scope || undefined; + scope.storage = scope.storage || 'sessionStorage'; + }; + + var compile = function() { + $http.get(scope.template, { + cache: $templateCache + }).then(function(html) { + element.html(html); + $compile(element.contents())(scope); + }); + }; + + var initProfile = function(scope) { + var token = AccessToken.get(); + + if (token && token.access_token && scope.profileUri) { + Profile.find(scope.profileUri).then(function(response) { + scope.profile = response; + }); + } + }; + + var initView = function() { + var token = AccessToken.get(); + + if (!token) { + return scope.login(); + } // without access token it's logged out, so we attempt to log in + if (AccessToken.expired()) { + return expired(); + } // with a token, but it's expired + if (token.access_token) { + return authorized(); + } // if there is the access token we are done + if (token.error) { + return denied(); + } // if the request has been denied we fire the denied event + }; + + scope.login = function() { + Endpoint.redirect(); + }; + + scope.logout = function() { + Endpoint.logout(); + $rootScope.$broadcast('oauth:loggedOut'); + scope.show = 'logged-out'; + }; + + scope.$on('oauth:expired', expired); + + // user is authorized + var authorized = function() { + $rootScope.$broadcast('oauth:authorized', AccessToken.get()); + scope.show = 'logged-in'; + }; + + var expired = function() { + $rootScope.$broadcast('oauth:expired'); + scope.logout(); + }; + + // set the oauth directive to the denied status + var denied = function() { + scope.show = 'denied'; + $rootScope.$broadcast('oauth:denied'); + }; + + var checkValidity = function() { + Endpoint.checkValidity().then(function() { + $rootScope.$broadcast('oauth:valid'); + }).catch(function(message) { + $rootScope.$broadcast('oauth:invalid', message); + }); + }; + + var refreshDirective = function() { + scope.$apply(); + }; + + // Updates the template at runtime + scope.$on('oauth:template:update', function(event, template) { + scope.template = template; + compile(scope); + }); + + // Hack to update the directive content on logout + scope.$on('$routeChangeSuccess', function() { + $timeout(refreshDirective); + }); + + scope.$on('$stateChangeSuccess', function() { + $timeout(refreshDirective); + }); + }; + + return definition; + } ]); diff --git a/test/spec/services/profile.js b/test/spec/services/profile.js index 0c195c4..c7664e8 100644 --- a/test/spec/services/profile.js +++ b/test/spec/services/profile.js @@ -2,119 +2,147 @@ describe('Profile', function() { - var $rootScope, $location, $httpBackend, $http, AccessToken, Profile; - var result, date, callback; + var $rootScope, $location, $httpBackend, $http, AccessToken, Profile; + var result, date, callback; + + var fragment = 'access_token=token&token_type=bearer&expires_in=7200&state=/path'; + var headers = { + 'Accept': 'application/json, text/plain, */*', + 'Authorization': 'Bearer token' + }; + var params = { + site: 'http://example.com', + client: 'client-id', + redirect: 'http://example.com/redirect', + scope: 'scope', + profileUri: 'http://example.com/me' + }; + var resource = { + id: '1', + name: 'Alice' + }; + + beforeEach(module('oauth')); + + beforeEach(inject(function($injector) { + $rootScope = $injector.get('$rootScope'); + })); + beforeEach(inject(function($injector) { + $location = $injector.get('$location'); + })); + beforeEach(inject(function($injector) { + $httpBackend = $injector.get('$httpBackend'); + })); + beforeEach(inject(function($injector) { + $http = $injector.get('$http'); + })); + beforeEach(inject(function($injector) { + AccessToken = $injector.get('AccessToken'); + })); + beforeEach(inject(function($injector) { + Profile = $injector.get('Profile'); + })); + + beforeEach(function() { + callback = jasmine.createSpy('callback'); + }); - var fragment = 'access_token=token&token_type=bearer&expires_in=7200&state=/path'; - var headers = { 'Accept': 'application/json, text/plain, */*', 'Authorization': 'Bearer token' }; - var params = { site: 'http://example.com', client: 'client-id', redirect: 'http://example.com/redirect', scope: 'scope', profileUri: 'http://example.com/me' }; - var resource = { id: '1', name: 'Alice' }; - beforeEach(module('oauth')); + describe('.get', function() { - beforeEach(inject(function($injector) { $rootScope = $injector.get('$rootScope'); })); - beforeEach(inject(function($injector) { $location = $injector.get('$location'); })); - beforeEach(inject(function($injector) { $httpBackend = $injector.get('$httpBackend'); })); - beforeEach(inject(function($injector) { $http = $injector.get('$http'); })); - beforeEach(inject(function($injector) { AccessToken = $injector.get('AccessToken'); })); - beforeEach(inject(function($injector) { Profile = $injector.get('Profile'); })); + describe('when authenticated', function() { - beforeEach(function() { callback = jasmine.createSpy('callback'); }); + beforeEach(function() { + $location.hash(fragment); + AccessToken.set(params); + }); + beforeEach(function() { + $httpBackend.whenGET('http://example.com/me', headers).respond(resource); + }); - describe('.get', function() { + describe('when gets the profile', function() { - describe('when authenticated', function() { + it('makes the request', function() { + $httpBackend.expect('GET', 'http://example.com/me'); + Profile.find(params.profileUri); + $rootScope.$apply(); + $httpBackend.flush(); + }); - beforeEach(function() { - $location.hash(fragment); - AccessToken.set(params); - }); + it('gets the resource', inject(function(Profile) { + Profile.find(params.profileUri).then(function(response) { + result = response; + }); + $rootScope.$apply(); + $httpBackend.flush(); + expect(result.name).toEqual('Alice'); + })); - beforeEach(function() { - $httpBackend.whenGET('http://example.com/me', headers).respond(resource); - }); + it('caches the profile', function() { + Profile.find(params.profileUri); + $rootScope.$apply(); + $httpBackend.flush(); + expect(Profile.get().name).toEqual('Alice'); + }); - describe('when gets the profile', function() { + it('fires oauth:profile event', function(done) { - it('makes the request', function() { - $httpBackend.expect('GET', 'http://example.com/me'); - Profile.find(params.profileUri); - $rootScope.$apply(); - $httpBackend.flush(); - }); + $rootScope.$on('oauth:profile', function(event, profile) { + expect(typeof profile).toBe('object'); + done(); + }); - it('gets the resource', inject(function(Profile) { - Profile.find(params.profileUri).success(function(response) { result = response; }); - $rootScope.$apply(); - $httpBackend.flush(); - expect(result.name).toEqual('Alice'); - })); - - it('caches the profile', function() { - Profile.find(params.profileUri); - $rootScope.$apply(); - $httpBackend.flush(); - expect(Profile.get().name).toEqual('Alice'); - }); + Profile.find(params.profileUri); + $rootScope.$apply(); + $httpBackend.flush(); - it('fires oauth:profile event', function(done) { + }); - $rootScope.$on('oauth:profile', function (event, profile) { - expect(typeof profile).toBe('object'); - done(); - }); - Profile.find(params.profileUri); - $rootScope.$apply(); - $httpBackend.flush(); + describe('when expired', function() { - }); + beforeEach(function() { + $rootScope.$on('oauth:expired', callback); + }); + beforeEach(function() { + date = new Date(); + date.setTime(date.getTime() + 86400000); + }); - describe('when expired', function() { + beforeEach(function() { + Timecop.install(); + Timecop.travel(date); // go one day in the future + }); - beforeEach(function() { - $rootScope.$on('oauth:expired', callback); - }); + afterEach(function() { + Timecop.uninstall(); + }); - beforeEach(function() { - date = new Date(); - date.setTime(date.getTime() + 86400000); - }); + it('fires the oauth:expired event', inject(function(Profile) { + Profile.find(params.profileUri); + $rootScope.$apply(); + $httpBackend.flush(); + var event = jasmine.any(Object); + var token = jasmine.any(Object); + expect(callback).toHaveBeenCalledWith(event, token); + })); + }); + }); - beforeEach(function() { - Timecop.install(); - Timecop.travel(date); // go one day in the future - }); - afterEach(function() { - Timecop.uninstall(); - }); + describe('when sets the profile', function() { - it('fires the oauth:expired event', inject(function(Profile) { - Profile.find(params.profileUri); - $rootScope.$apply(); - $httpBackend.flush(); - var event = jasmine.any(Object); - var token = jasmine.any(Object); - expect(callback).toHaveBeenCalledWith(event, token); - })); - }); - }); + beforeEach(function() { + Profile.set(resource); + }); + it('caches the profile', function() { + expect(Profile.get().name).toEqual('Alice'); + }); - describe('when sets the profile', function() { - - beforeEach(function() { - Profile.set(resource); - }); - - it('caches the profile', function() { - expect(Profile.get().name).toEqual('Alice'); + }); }); - - }); }); - }); }); From 8302f367678b26081345efc4c56bad78db43e3c3 Mon Sep 17 00:00:00 2001 From: Roman Mahrer Date: Thu, 15 Dec 2016 17:03:07 +0100 Subject: [PATCH 2/4] using response.data for .then() callback --- app/scripts/directives/oauth.js | 6 +++--- test/spec/services/profile.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/scripts/directives/oauth.js b/app/scripts/directives/oauth.js index b1c7aed..6642c3a 100644 --- a/app/scripts/directives/oauth.js +++ b/app/scripts/directives/oauth.js @@ -79,8 +79,8 @@ directives.directive('oauth', [ var compile = function() { $http.get(scope.template, { cache: $templateCache - }).then(function(html) { - element.html(html); + }).then(function(response) { + element.html(response.data); $compile(element.contents())(scope); }); }; @@ -90,7 +90,7 @@ directives.directive('oauth', [ if (token && token.access_token && scope.profileUri) { Profile.find(scope.profileUri).then(function(response) { - scope.profile = response; + scope.profile = response.data; }); } }; diff --git a/test/spec/services/profile.js b/test/spec/services/profile.js index c7664e8..e2a11d5 100644 --- a/test/spec/services/profile.js +++ b/test/spec/services/profile.js @@ -72,7 +72,7 @@ describe('Profile', function() { it('gets the resource', inject(function(Profile) { Profile.find(params.profileUri).then(function(response) { - result = response; + result = response.data; }); $rootScope.$apply(); $httpBackend.flush(); From 68704fc73606772e4efd8ceabeac9f170bee5e11 Mon Sep 17 00:00:00 2001 From: Roman Mahrer Date: Thu, 15 Dec 2016 17:04:53 +0100 Subject: [PATCH 3/4] build dist --- dist/oauth-ng.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/oauth-ng.js b/dist/oauth-ng.js index 5524161..3c33c42 100644 --- a/dist/oauth-ng.js +++ b/dist/oauth-ng.js @@ -904,8 +904,8 @@ directives.directive('oauth', [ var compile = function() { $http.get(scope.template, { cache: $templateCache - }).then(function(html) { - element.html(html); + }).then(function(response) { + element.html(response.data); $compile(element.contents())(scope); }); }; @@ -915,7 +915,7 @@ directives.directive('oauth', [ if (token && token.access_token && scope.profileUri) { Profile.find(scope.profileUri).then(function(response) { - scope.profile = response; + scope.profile = response.data; }); } }; From 40e43bb8543304e453c1d237627de606b4721a9c Mon Sep 17 00:00:00 2001 From: Roman Mahrer Date: Thu, 15 Dec 2016 17:13:15 +0100 Subject: [PATCH 4/4] bower angular resolution back to 1.3.20 --- bower.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index f51dde3..1b00e63 100644 --- a/bower.json +++ b/bower.json @@ -14,7 +14,7 @@ "package.json" ], "dependencies": { - "angular": "~1.6.0", + "angular": "~1.3.12", "ngstorage": "~0.3.0", "jsrsasign": "~5.0.5" }, @@ -27,6 +27,6 @@ "angular-mocks": "~1.3.12" }, "resolutions": { - "angular": "1.6.0" + "angular": "1.3.20" } }