From c2bda8fd57a2582dbe7cc51ba441d53d5de579bc Mon Sep 17 00:00:00 2001 From: Vincens Mink Date: Mon, 7 Apr 2014 13:07:58 +0100 Subject: [PATCH 01/42] Updated README with configUpdater function Described how to use the config updater function in an Advanced use case section. Have not changed anything, just added. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 3b7e1a6..967f707 100644 --- a/README.md +++ b/README.md @@ -41,3 +41,9 @@ to HTTP 401 response. * your initial failed request will now be retried and when proper response is finally received, the `function(response) {do-something-with-response}` will fire, * your application will continue as nothing had happened. + +###Advanced use case: +Same beginning as before but, +* once your application figures out the authentication is OK, call: `authService.loginConfirmed([data], [updateConfigFunc)`, +* your initial failed request will now be retried but you can supply additional data to observers who are listening for `event:auth-loginConfirmed`, and all your queued http requests will be recalculated by your `updateConfigFunc(httpConfig)` function. This is very usefull if you need to update the headers with new credentials and/or tokens from your successful login. + From ffd5bf177b90121df2a53c6a936d6680d9eecf2a Mon Sep 17 00:00:00 2001 From: Vincens Mink Date: Mon, 7 Apr 2014 14:21:53 +0100 Subject: [PATCH 02/42] Fixed typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 967f707..8b53e65 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,6 @@ the `function(response) {do-something-with-response}` will fire, ###Advanced use case: Same beginning as before but, -* once your application figures out the authentication is OK, call: `authService.loginConfirmed([data], [updateConfigFunc)`, +* once your application figures out the authentication is OK, call: `authService.loginConfirmed([data], [updateConfigFunc])`, * your initial failed request will now be retried but you can supply additional data to observers who are listening for `event:auth-loginConfirmed`, and all your queued http requests will be recalculated by your `updateConfigFunc(httpConfig)` function. This is very usefull if you need to update the headers with new credentials and/or tokens from your successful login. From 5725eb7d289480c22fe10364df0aa432852691fe Mon Sep 17 00:00:00 2001 From: Elnur Abdurrakhimov Date: Sun, 6 Jul 2014 05:24:26 +0400 Subject: [PATCH 03/42] Fix a typo --- src/http-auth-interceptor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index ee05847..3b9bfcc 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -40,7 +40,7 @@ /** * $http interceptor. * On 401 response (without 'ignoreAuthModule' option) stores the request - * and broadcasts 'event:angular-auth-loginRequired'. + * and broadcasts 'event:auth-loginRequired'. */ .config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function($rootScope, $q, httpBuffer) { From 6191b43d9e7084276c448dde96a6a43560834084 Mon Sep 17 00:00:00 2001 From: Alexander Kjeldaas Date: Wed, 13 Aug 2014 12:58:26 +0200 Subject: [PATCH 04/42] More documentation for loginConfirmed (#66) --- src/http-auth-interceptor.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index 3b9bfcc..bb1e12b 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -17,6 +17,10 @@ * retry of all deferred requests. * @param data an optional argument to pass on to $broadcast which may be useful for * example if you need to pass through details of the user that was logged in + * @param configUpdater an optional transformation function that can modify the + * $http configuration object for requests that are retried + * after having logged in. This can be used for example to add + * an authentication token. It must return the modified configuration object. */ loginConfirmed: function(data, configUpdater) { var updater = configUpdater || function(config) {return config;}; From 8e5a689ec2bcf03f952822e9e6915a2dc7cb560f Mon Sep 17 00:00:00 2001 From: Alexander Kjeldaas Date: Thu, 11 Sep 2014 15:08:39 +0200 Subject: [PATCH 05/42] Uppdated in response to review --- src/http-auth-interceptor.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index bb1e12b..1f787ab 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -18,9 +18,8 @@ * @param data an optional argument to pass on to $broadcast which may be useful for * example if you need to pass through details of the user that was logged in * @param configUpdater an optional transformation function that can modify the - * $http configuration object for requests that are retried - * after having logged in. This can be used for example to add - * an authentication token. It must return the modified configuration object. + * requests that are retried after having logged in. This can be used for example + * to add an authentication token. It must return the request. */ loginConfirmed: function(data, configUpdater) { var updater = configUpdater || function(config) {return config;}; From 21746994d76c6e57f86e1f014400840b0d10c91c Mon Sep 17 00:00:00 2001 From: Kris Willis Date: Sat, 13 Sep 2014 14:42:50 +0100 Subject: [PATCH 06/42] Added support for HTTP 403 responses --- README.md | 4 ++++ src/http-auth-interceptor.js | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8b53e65..7afc475 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,10 @@ $broadcast. This may be useful, for example if you need to pass through details that was logged in. The `authService` will then retry all the requests previously failed due to HTTP 401 response. +In the event that a requested resource returns an HTTP 403 response (i.e. the user is +authenticated but not authorized to access the resource), the user's request is discarded and +the 'event:auth-authorizationRequired' message is broadcased from $rootScope. + ###Typical use case: * somewhere (some service or controller) the: `$http(...).then(function(response) { do-something-with-response })` is invoked, diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index 1f787ab..a570353 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -44,16 +44,24 @@ * $http interceptor. * On 401 response (without 'ignoreAuthModule' option) stores the request * and broadcasts 'event:auth-loginRequired'. + * On 403 response (without 'ignoreAuthModule' option) discards the request + * and broadcasts 'event:auth-authorizationRequired'. */ .config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function($rootScope, $q, httpBuffer) { return { responseError: function(rejection) { - if (rejection.status === 401 && !rejection.config.ignoreAuthModule) { - var deferred = $q.defer(); - httpBuffer.append(rejection.config, deferred); - $rootScope.$broadcast('event:auth-loginRequired', rejection); - return deferred.promise; + if (!rejection.config.ignoreAuthModule) { + switch (rejection.status) { + case 401: + var deferred = $q.defer(); + httpBuffer.append(rejection.config, deferred); + $rootScope.$broadcast('event:auth-loginRequired', rejection); + return deferred.promise; + case 403: + $rootScope.$broadcast('event:auth-authorizationRequired', rejection); + break; + } } // otherwise, default behaviour return $q.reject(rejection); From da32cf6ac6e4a99121d78898f0dc63e73e5f0371 Mon Sep 17 00:00:00 2001 From: Kris Willis Date: Sat, 13 Sep 2014 14:45:06 +0100 Subject: [PATCH 07/42] Tweaked README formatting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7afc475..573cfe4 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ to HTTP 401 response. In the event that a requested resource returns an HTTP 403 response (i.e. the user is authenticated but not authorized to access the resource), the user's request is discarded and -the 'event:auth-authorizationRequired' message is broadcased from $rootScope. +the `event:auth-authorizationRequired` message is broadcased from $rootScope. ###Typical use case: From 298a8a2512e4602c8d2945281d465e5694dceffd Mon Sep 17 00:00:00 2001 From: Kris Willis Date: Sun, 14 Sep 2014 12:54:59 +0100 Subject: [PATCH 08/42] Changed broadcasted message for 403 responses to event:auth-forbidden --- README.md | 2 +- src/http-auth-interceptor.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 573cfe4..c71e9c9 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ to HTTP 401 response. In the event that a requested resource returns an HTTP 403 response (i.e. the user is authenticated but not authorized to access the resource), the user's request is discarded and -the `event:auth-authorizationRequired` message is broadcased from $rootScope. +the `event:auth-forbidden` message is broadcased from $rootScope. ###Typical use case: diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index a570353..89f15c5 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -59,7 +59,7 @@ $rootScope.$broadcast('event:auth-loginRequired', rejection); return deferred.promise; case 403: - $rootScope.$broadcast('event:auth-authorizationRequired', rejection); + $rootScope.$broadcast('event:auth-forbidden', rejection); break; } } From bec90211578187c4b59b8dee478fe9eb74a8c3b1 Mon Sep 17 00:00:00 2001 From: Kris Willis Date: Sun, 14 Sep 2014 12:59:15 +0100 Subject: [PATCH 09/42] Fixed typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c71e9c9..5347d56 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ to HTTP 401 response. In the event that a requested resource returns an HTTP 403 response (i.e. the user is authenticated but not authorized to access the resource), the user's request is discarded and -the `event:auth-forbidden` message is broadcased from $rootScope. +the `event:auth-forbidden` message is broadcasted from $rootScope. ###Typical use case: From f99e8a671ce9da3cfa7596a82ab2210e329c3980 Mon Sep 17 00:00:00 2001 From: Kris Willis Date: Sun, 14 Sep 2014 13:00:48 +0100 Subject: [PATCH 10/42] Fixed docs --- src/http-auth-interceptor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index 89f15c5..7e85967 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -45,7 +45,7 @@ * On 401 response (without 'ignoreAuthModule' option) stores the request * and broadcasts 'event:auth-loginRequired'. * On 403 response (without 'ignoreAuthModule' option) discards the request - * and broadcasts 'event:auth-authorizationRequired'. + * and broadcasts 'event:auth-forbidden'. */ .config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function($rootScope, $q, httpBuffer) { From 261484df0ae55fb41f46c32299fc748a0a71b699 Mon Sep 17 00:00:00 2001 From: Batoure Date: Sun, 14 Dec 2014 08:11:27 -0800 Subject: [PATCH 11/42] Clarified Advanced Use cases Added specific detail to the advanced use cases to make them more clear. --- README.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5347d56..2b0c695 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,31 @@ the `function(response) {do-something-with-response}` will fire, * your application will continue as nothing had happened. ###Advanced use case: -Same beginning as before but, -* once your application figures out the authentication is OK, call: `authService.loginConfirmed([data], [updateConfigFunc])`, -* your initial failed request will now be retried but you can supply additional data to observers who are listening for `event:auth-loginConfirmed`, and all your queued http requests will be recalculated by your `updateConfigFunc(httpConfig)` function. This is very usefull if you need to update the headers with new credentials and/or tokens from your successful login. + +####Sending data to listeners: +You can supply additional data to observers accross your application who are listening for `event:auth-loginConfirmed`: + + $scope.$on('event:auth-loginConfirmed', function(event, data){ + $rootScope.isLoggedin = true; + $log.log(data) + }); + +Use the `authService.loginConfirmed([data])` method to emit data with your login event. + +####Updating [$http(config)](https://docs.angularjs.org/api/ng/service/$http): +Successful login means that the previous request are ready to be fired again, however now that login has occured certain aspects of the previous requests might need to be modified on the fly. This is particularly important in a token based authentication scheme where an authorization token should be added to the header. + +The `loginConfirmed` method supports the injection of an Updater function that will apply changes to the http config object. + + authService.loginConfirmed([data], [Updater-Function]) + + //application of tokens to previously fired requests: + var token = reponse.token; + + authService.loginConfirmed('success', function(config){ + config.headers["Authorization"] = token; + return config; + }) + +The initial failed request will now be retried, all queued http requests will be recalculated using the Updater-Function. From 4fed0569ed809229d563df7701d7b2b9f76d2fb9 Mon Sep 17 00:00:00 2001 From: Tom Caflisch Date: Tue, 16 Dec 2014 14:42:10 -0600 Subject: [PATCH 12/42] Update README.md At the very least include how to use this module. It's an awesome module, but extremely confusing documentation. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 5347d56..a0bbf51 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,12 @@ Launch demo [here](http://witoldsz.github.com/angular-http-auth/) or switch to [gh-pages](https://github.com/witoldsz/angular-http-auth/tree/gh-pages) branch for source code of the demo. +Usage +------ + +- Install via bower: `bower install --save` +- Include as a dependency in your app: `angular.module('myApp', ['http-auth-interceptor'])` + Manual ------ From 6fdcbcd098cf90417171af9d7ed0f44396b993d0 Mon Sep 17 00:00:00 2001 From: Lukas Elmer Date: Sat, 17 Jan 2015 00:48:25 +0100 Subject: [PATCH 13/42] Fix link to blog --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b0c695..0e195d4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ for AngularJS ------------- This is the implementation of the concept described in -[Authentication in AngularJS (or similar) based application](http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application). +[Authentication in AngularJS (or similar) based application](http://www.espeo.pl/1-authentication-in-angularjs-application/). There are releases for both AngularJS **1.0.x** and **1.2.x**, see [releases](https://github.com/witoldsz/angular-http-auth/releases). From 58088b07787f221db19348ed0389d1a4301e5145 Mon Sep 17 00:00:00 2001 From: Matt Conroy Date: Thu, 22 Jan 2015 15:45:56 -0700 Subject: [PATCH 14/42] - Spelling correction --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0529fc7..22c373d 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ the `function(response) {do-something-with-response}` will fire, ###Advanced use case: ####Sending data to listeners: -You can supply additional data to observers accross your application who are listening for `event:auth-loginConfirmed`: +You can supply additional data to observers across your application who are listening for `event:auth-loginConfirmed`: $scope.$on('event:auth-loginConfirmed', function(event, data){ $rootScope.isLoggedin = true; From 5c6970c90c61568c846f2f321d1111432398a0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20Sj=C3=B6blad?= Date: Fri, 30 Jan 2015 12:00:02 +0200 Subject: [PATCH 15/42] =?UTF-8?q?Added=20information=20about=20the=20?= =?UTF-8?q?=C2=B4ignoreAuthModule=C2=B4=20config=20flag=20to=20the=20READM?= =?UTF-8?q?E=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 22c373d..938ab16 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,10 @@ In the event that a requested resource returns an HTTP 403 response (i.e. the us authenticated but not authorized to access the resource), the user's request is discarded and the `event:auth-forbidden` message is broadcasted from $rootScope. +#### Ignoring the 401 interceptor + +Sometimes you might not want the intercepter to intercept a request even if one returns 401 or 403. In a case like this you can add `ignoreAuthModule: true` to the request config. A common use case for this would be, for example, a login request which returns 401 if the login credentials are invalid. + ###Typical use case: * somewhere (some service or controller) the: `$http(...).then(function(response) { do-something-with-response })` is invoked, From a1a29023af0b0463dabe47f10645039930325c87 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 30 Apr 2015 21:28:27 -0500 Subject: [PATCH 16/42] Update README.md add bower module name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 938ab16..fc5e301 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ branch for source code of the demo. Usage ------ -- Install via bower: `bower install --save` +- Install via bower: `bower install --save angular-http-auth` - Include as a dependency in your app: `angular.module('myApp', ['http-auth-interceptor'])` Manual From f052ab5a53ea4b9bc684a2bf31d3a06895cad6c7 Mon Sep 17 00:00:00 2001 From: Luke Waite Date: Fri, 8 May 2015 11:58:24 -0400 Subject: [PATCH 17/42] Update version to match current release --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 8b02643..32bcab8 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "author": "Witold Szczerba", "name": "angular-http-auth", - "version": "1.2.1", + "version": "1.2.2", "homepage": "https://github.com/witoldsz/angular-http-auth", "repository": { "type": "git", From 1eb4a08d08b400956c0848f84d8fcaa9ad1357a2 Mon Sep 17 00:00:00 2001 From: Tamlyn Rhodes Date: Fri, 22 May 2015 15:59:05 +0100 Subject: [PATCH 18/42] Added package.json for npm compatibility --- package.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..53f2424 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "angular-http-auth", + "version": "1.2.2", + "description": "HTTP Auth Interceptor Module", + "repository": { + "type": "git", + "url": "https://github.com/witoldsz/angular-http-auth.git" + }, + "keywords": [ + "angular", + "auth" + ], + "license": "MIT", + "homepage": "https://github.com/witoldsz/angular-http-auth" +} From 871a04ea6b903778767902bef0fbef64042146dd Mon Sep 17 00:00:00 2001 From: Witold Szczerba Date: Sat, 6 Jun 2015 23:46:31 +0200 Subject: [PATCH 19/42] npm: introducing package.json --- README.md | 11 ++++++----- package.json | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 package.json diff --git a/README.md b/README.md index fc5e301..1de0e2c 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Usage ------ - Install via bower: `bower install --save angular-http-auth` +- ...or via npm: `npm install --save angular-http-auth` - Include as a dependency in your app: `angular.module('myApp', ['http-auth-interceptor'])` Manual @@ -36,8 +37,8 @@ $broadcast. This may be useful, for example if you need to pass through details that was logged in. The `authService` will then retry all the requests previously failed due to HTTP 401 response. -In the event that a requested resource returns an HTTP 403 response (i.e. the user is -authenticated but not authorized to access the resource), the user's request is discarded and +In the event that a requested resource returns an HTTP 403 response (i.e. the user is +authenticated but not authorized to access the resource), the user's request is discarded and the `event:auth-forbidden` message is broadcasted from $rootScope. #### Ignoring the 401 interceptor @@ -59,7 +60,7 @@ the `function(response) {do-something-with-response}` will fire, ###Advanced use case: ####Sending data to listeners: -You can supply additional data to observers across your application who are listening for `event:auth-loginConfirmed`: +You can supply additional data to observers across your application who are listening for `event:auth-loginConfirmed`: $scope.$on('event:auth-loginConfirmed', function(event, data){ $rootScope.isLoggedin = true; @@ -74,10 +75,10 @@ Successful login means that the previous request are ready to be fired again, ho The `loginConfirmed` method supports the injection of an Updater function that will apply changes to the http config object. authService.loginConfirmed([data], [Updater-Function]) - + //application of tokens to previously fired requests: var token = reponse.token; - + authService.loginConfirmed('success', function(config){ config.headers["Authorization"] = token; return config; diff --git a/package.json b/package.json new file mode 100644 index 0000000..93abcdc --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "angular-http-auth", + "version": "1.2.1", + "description": "HTTP Auth Interceptor Module for AngularJS.", + "main": "src/http-auth-interceptor.js", + "repository": { + "type": "git", + "url": "https://github.com/witoldsz/angular-http-auth.git" + }, + "author": "Witold Szczerba", + "license": "MIT", + "bugs": { + "url": "https://github.com/witoldsz/angular-http-auth/issues" + }, + "homepage": "https://github.com/witoldsz/angular-http-auth" +} \ No newline at end of file From 7f9abe3821f7d1ab69c25c6baa1a2c48a84a1e9a Mon Sep 17 00:00:00 2001 From: Kevin Kirsche Date: Thu, 11 Jun 2015 21:12:03 -0400 Subject: [PATCH 20/42] Remove moot `version` property from bower.json Per bower/bower.json-spec@a325da3 Also their maintainer says they probably won't ever use it: http://stackoverflow.com/questions/24844901/bowers-bower-json-file-version-property --- bower.json | 1 - 1 file changed, 1 deletion(-) diff --git a/bower.json b/bower.json index 32bcab8..ec556d4 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,6 @@ { "author": "Witold Szczerba", "name": "angular-http-auth", - "version": "1.2.2", "homepage": "https://github.com/witoldsz/angular-http-auth", "repository": { "type": "git", From 46b25d70ae77be7f7a7cff8769d3cd69854b17fc Mon Sep 17 00:00:00 2001 From: Luke Waite Date: Sat, 31 Oct 2015 21:14:46 -0400 Subject: [PATCH 21/42] tweak readme formatting --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1de0e2c..9d92e0d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ the configuration object (this is the requested URL, payload and parameters) of every HTTP 401 response is buffered and everytime it happens, the `event:auth-loginRequired` message is broadcasted from $rootScope. -The `authService` has only one method: #loginConfirmed(). +The `authService` has only one method: `loginConfirmed()`. You are responsible to invoke this method after user logged in. You may optionally pass in a data argument to the loginConfirmed method which will be passed on to the loginConfirmed $broadcast. This may be useful, for example if you need to pass through details of the user @@ -39,11 +39,11 @@ to HTTP 401 response. In the event that a requested resource returns an HTTP 403 response (i.e. the user is authenticated but not authorized to access the resource), the user's request is discarded and -the `event:auth-forbidden` message is broadcasted from $rootScope. +the `event:auth-forbidden` message is broadcast from $rootScope. #### Ignoring the 401 interceptor -Sometimes you might not want the intercepter to intercept a request even if one returns 401 or 403. In a case like this you can add `ignoreAuthModule: true` to the request config. A common use case for this would be, for example, a login request which returns 401 if the login credentials are invalid. +Sometimes you might not want the interceptor to intercept a request even if one returns 401 or 403. In a case like this you can add `ignoreAuthModule: true` to the request config. A common use case for this would be, for example, a login request which returns 401 if the login credentials are invalid. ###Typical use case: @@ -70,7 +70,7 @@ You can supply additional data to observers across your application who are list Use the `authService.loginConfirmed([data])` method to emit data with your login event. ####Updating [$http(config)](https://docs.angularjs.org/api/ng/service/$http): -Successful login means that the previous request are ready to be fired again, however now that login has occured certain aspects of the previous requests might need to be modified on the fly. This is particularly important in a token based authentication scheme where an authorization token should be added to the header. +Successful login means that the previous request are ready to be fired again, however now that login has occurred certain aspects of the previous requests might need to be modified on the fly. This is particularly important in a token based authentication scheme where an authorization token should be added to the header. The `loginConfirmed` method supports the injection of an Updater function that will apply changes to the http config object. From 3f5403672952b8c525e73f0ad8aca05d80f3aa86 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 3 Nov 2015 16:44:25 -0600 Subject: [PATCH 22/42] Add missing ignore to bower.json https://github.com/bower/spec/blob/master/json.md#ignore Because bower complains about it: ```bash $ bower install --save angular-http-auth bower angular-http-auth#* not-cached git://github.com/witoldsz/angular-http-auth.git#* bower angular-http-auth#* resolve git://github.com/witoldsz/angular-http-auth.git#* bower angular-http-auth#* download https://github.com/witoldsz/angular-http-auth/archive/v1.2.2.tar.gz bower angular-http-auth#* extract archive.tar.gz bower angular-http-auth#* mismatch Version declared in the json (1.2.1) is different than the resolved one (1.2.2) bower angular-http-auth#* invalid-meta angular-http-auth is missing "ignore" entry in bower.json bower angular-http-auth#* resolved git://github.com/witoldsz/angular-http-auth.git#1.2.2 bower angular-http-auth#~1.2.2 install angular-http-auth#1.2.2 ``` Closes #111 --- bower.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bower.json b/bower.json index ec556d4..27daaaf 100644 --- a/bower.json +++ b/bower.json @@ -9,5 +9,8 @@ "main": "./src/http-auth-interceptor.js", "dependencies": { "angular": "^1.2" - } + }, + "ignore": [ + "package.json" + ] } From 2c46a956cb28cb74b6e87467e88f17b9a4aed0d8 Mon Sep 17 00:00:00 2001 From: Witold Szczerba Date: Thu, 12 Nov 2015 00:18:47 +0100 Subject: [PATCH 23/42] Error when config doesn't exist, issue #118 --- src/http-auth-interceptor.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index 7e85967..95e3426 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -17,7 +17,7 @@ * retry of all deferred requests. * @param data an optional argument to pass on to $broadcast which may be useful for * example if you need to pass through details of the user that was logged in - * @param configUpdater an optional transformation function that can modify the + * @param configUpdater an optional transformation function that can modify the * requests that are retried after having logged in. This can be used for example * to add an authentication token. It must return the request. */ @@ -51,11 +51,12 @@ $httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function($rootScope, $q, httpBuffer) { return { responseError: function(rejection) { - if (!rejection.config.ignoreAuthModule) { + var config = rejection.config || {}; + if (!config.ignoreAuthModule) { switch (rejection.status) { case 401: var deferred = $q.defer(); - httpBuffer.append(rejection.config, deferred); + httpBuffer.append(config, deferred); $rootScope.$broadcast('event:auth-loginRequired', rejection); return deferred.promise; case 403: From e599bc0b1b69a5d2f87a3594ad42c4bd7b992b78 Mon Sep 17 00:00:00 2001 From: Witold Szczerba Date: Tue, 24 Nov 2015 23:53:52 +0100 Subject: [PATCH 24/42] 1.2.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a91374c..7171764 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-http-auth", - "version": "1.2.2", + "version": "1.2.3", "description": "HTTP Auth Interceptor Module for AngularJS.", "main": "src/http-auth-interceptor.js", "repository": { From 95517bb083f4bdae54a10b592bb4c1b64dfeae77 Mon Sep 17 00:00:00 2001 From: Stig Otnes Kolstad Date: Thu, 17 Dec 2015 14:57:10 +0100 Subject: [PATCH 25/42] FIxed broken link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d92e0d..306724d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ for AngularJS ------------- This is the implementation of the concept described in -[Authentication in AngularJS (or similar) based application](http://www.espeo.pl/1-authentication-in-angularjs-application/). +[Authentication in AngularJS (or similar) based application](http://espeo.eu/blog/authentication-in-angularjs-or-similar-based-application/). There are releases for both AngularJS **1.0.x** and **1.2.x**, see [releases](https://github.com/witoldsz/angular-http-auth/releases). From 2ab907ee49860050c6f7deb70e7cece0f3aa67c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Gajek?= Date: Wed, 24 Feb 2016 21:20:48 +0100 Subject: [PATCH 26/42] loginConfirmed: updater returns false to ignore request allow the request to be ignored from "retrying" when loginConfirmed's updater function returns ``false`` --- src/http-auth-interceptor.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index 95e3426..34d5650 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -122,7 +122,10 @@ */ retryAll: function(updater) { for (var i = 0; i < buffer.length; ++i) { - retryHttpRequest(updater(buffer[i].config), buffer[i].deferred); + var _cfg = updater(buffer[i].config); + if (_cfg === false) + continue; + retryHttpRequest(_cfg, buffer[i].deferred); } buffer = []; } From a79e9fc26e6a90a31ee141d105c2ac0d637df7f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Gajek?= Date: Tue, 1 Mar 2016 08:28:09 +0100 Subject: [PATCH 27/42] inverted "if" statement to remove "continue" --- src/http-auth-interceptor.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index 34d5650..c2e62ed 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -123,9 +123,8 @@ retryAll: function(updater) { for (var i = 0; i < buffer.length; ++i) { var _cfg = updater(buffer[i].config); - if (_cfg === false) - continue; - retryHttpRequest(_cfg, buffer[i].deferred); + if (_cfg !== false) + retryHttpRequest(_cfg, buffer[i].deferred); } buffer = []; } From 472e6a2bdcc2e5ee6eea98629c3418e71f1723bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Gajek?= Date: Tue, 1 Mar 2016 08:36:22 +0100 Subject: [PATCH 28/42] updated the docs: skip specific request retry --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 306724d..b62af87 100644 --- a/README.md +++ b/README.md @@ -86,3 +86,10 @@ The `loginConfirmed` method supports the injection of an Updater function that w The initial failed request will now be retried, all queued http requests will be recalculated using the Updater-Function. +It is also possible to stop specific request from being retried, by returning ``false`` from the Updater-Function: + + authService.loginConfirmed('success', function(config){ + if (shouldSkipRetryOnSuccess(config)) + return false; + return config; + }) From 1e26e442e8b6d2d9e92b29dae1f0abb38adb1af8 Mon Sep 17 00:00:00 2001 From: Witold Szczerba Date: Wed, 23 Mar 2016 00:50:48 +0100 Subject: [PATCH 29/42] prevent repeating `event:auth-loginRequired` #95 #120 #130 --- src/http-auth-interceptor.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index c2e62ed..0fd9789 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -56,8 +56,9 @@ switch (rejection.status) { case 401: var deferred = $q.defer(); - httpBuffer.append(config, deferred); - $rootScope.$broadcast('event:auth-loginRequired', rejection); + var bufferLength = httpBuffer.append(config, deferred); + if (bufferLength === 1) + $rootScope.$broadcast('event:auth-loginRequired', rejection); return deferred.promise; case 403: $rootScope.$broadcast('event:auth-forbidden', rejection); @@ -97,9 +98,10 @@ return { /** * Appends HTTP request configuration object with deferred response attached to buffer. + * @return {Number} The new length of the buffer. */ append: function(config, deferred) { - buffer.push({ + return buffer.push({ config: config, deferred: deferred }); From 10914bf218f436ce2de14eec6b3b319209b3aa4b Mon Sep 17 00:00:00 2001 From: Witold Szczerba Date: Fri, 25 Mar 2016 00:39:04 +0100 Subject: [PATCH 30/42] 1.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7171764..1fc46cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-http-auth", - "version": "1.2.3", + "version": "1.3.0", "description": "HTTP Auth Interceptor Module for AngularJS.", "main": "src/http-auth-interceptor.js", "repository": { From 55aa8512ea716df36445a8231010d5e33f6a2adc Mon Sep 17 00:00:00 2001 From: John Wnek Date: Sat, 9 Apr 2016 12:51:50 -0400 Subject: [PATCH 31/42] adding loginCancelled documentation to README --- README.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b62af87..52fdb11 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,19 @@ the configuration object (this is the requested URL, payload and parameters) of every HTTP 401 response is buffered and everytime it happens, the `event:auth-loginRequired` message is broadcasted from $rootScope. -The `authService` has only one method: `loginConfirmed()`. -You are responsible to invoke this method after user logged in. You may optionally pass in -a data argument to the loginConfirmed method which will be passed on to the loginConfirmed +The `authService` has only 2 methods: `loginConfirmed()` and `loginCancelled()`. + +You are responsible to invoke `loginConfirmed()` after user logs in. You may optionally pass in +a data argument to this method which will be passed on to the loginConfirmed $broadcast. This may be useful, for example if you need to pass through details of the user that was logged in. The `authService` will then retry all the requests previously failed due to HTTP 401 response. +You are responsible to invoke `loginCancelled()` when authentication has been invalidated. You may optionally pass in +a data argument to this method which will be passed on to the loginCancelled +$broadcast. The `authService` will cancel all pending requests previously failed and buffered due +to HTTP 401 response. + In the event that a requested resource returns an HTTP 403 response (i.e. the user is authenticated but not authorized to access the resource), the user's request is discarded and the `event:auth-forbidden` message is broadcast from $rootScope. @@ -60,14 +66,19 @@ the `function(response) {do-something-with-response}` will fire, ###Advanced use case: ####Sending data to listeners: -You can supply additional data to observers across your application who are listening for `event:auth-loginConfirmed`: +You can supply additional data to observers across your application who are listening for `event:auth-loginConfirmed` and `event:auth-loginCancelled`: $scope.$on('event:auth-loginConfirmed', function(event, data){ $rootScope.isLoggedin = true; $log.log(data) }); -Use the `authService.loginConfirmed([data])` method to emit data with your login event. + $scope.$on('event:auth-loginCancelled', function(event, data){ + $rootScope.isLoggedin = false; + $log.log(data) + }); + +Use the `authService.loginConfirmed([data])` and `authService.loginCancelled([data])` methods to emit data with your login and logout events. ####Updating [$http(config)](https://docs.angularjs.org/api/ng/service/$http): Successful login means that the previous request are ready to be fired again, however now that login has occurred certain aspects of the previous requests might need to be modified on the fly. This is particularly important in a token based authentication scheme where an authorization token should be added to the header. From 5437350dbe412e7b039aacd1231a16a7aba27e1c Mon Sep 17 00:00:00 2001 From: Stephen Pengilley Date: Wed, 9 Nov 2016 15:20:53 +0000 Subject: [PATCH 32/42] Grunt uglification Minified js file --- .gitignore | 1 + Gruntfile.js | 23 +++++++++++++++++++++++ package.json | 8 +++++++- src/http-auth-interceptor.min.js | 1 + tasks/uglify.js | 20 ++++++++++++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 Gruntfile.js create mode 100644 src/http-auth-interceptor.min.js create mode 100644 tasks/uglify.js diff --git a/.gitignore b/.gitignore index 522163c..67a0dad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules +npm-debug.log bower_components components diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..96d7d29 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,23 @@ +/** + * @license HTTP Auth Interceptor Module for AngularJS + * License: MIT + */ + +"use strict" + +module.exports = function(grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json') + }); + + grunt.loadTasks('tasks'); + + grunt.registerTask('default', function() { + grunt.log.ok("HTTP Auth Interceptor Module for AngularJS"); + grunt.log.ok("============================"); + grunt.task.run(["uglify"]); + grunt.log.ok("Minified ok"); + }); + +}; diff --git a/package.json b/package.json index 1fc46cb..d8781e7 100644 --- a/package.json +++ b/package.json @@ -16,5 +16,11 @@ "angular", "auth" ], - "homepage": "https://github.com/witoldsz/angular-http-auth" + "homepage": "https://github.com/witoldsz/angular-http-auth", + "devDependencies": { + "grunt": "^0.4.5", + "grunt-contrib-uglify": "^0.11.0", + "load-grunt-config": "^0.19.1", + "time-grunt": "^1.3.0" + } } diff --git a/src/http-auth-interceptor.min.js b/src/http-auth-interceptor.min.js new file mode 100644 index 0000000..d3de029 --- /dev/null +++ b/src/http-auth-interceptor.min.js @@ -0,0 +1 @@ +/* angular-http-auth - 1.3.0 / Witold Szczerba */!function(){"use strict";angular.module("http-auth-interceptor",["http-auth-interceptor-buffer"]).factory("authService",["$rootScope","httpBuffer",function($rootScope,httpBuffer){return{loginConfirmed:function(data,configUpdater){var updater=configUpdater||function(config){return config};$rootScope.$broadcast("event:auth-loginConfirmed",data),httpBuffer.retryAll(updater)},loginCancelled:function(data,reason){httpBuffer.rejectAll(reason),$rootScope.$broadcast("event:auth-loginCancelled",data)}}}]).config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$rootScope","$q","httpBuffer",function($rootScope,$q,httpBuffer){return{responseError:function(rejection){var config=rejection.config||{};if(!config.ignoreAuthModule)switch(rejection.status){case 401:var deferred=$q.defer(),bufferLength=httpBuffer.append(config,deferred);return 1===bufferLength&&$rootScope.$broadcast("event:auth-loginRequired",rejection),deferred.promise;case 403:$rootScope.$broadcast("event:auth-forbidden",rejection)}return $q.reject(rejection)}}}])}]),angular.module("http-auth-interceptor-buffer",[]).factory("httpBuffer",["$injector",function($injector){function retryHttpRequest(config,deferred){function successCallback(response){deferred.resolve(response)}function errorCallback(response){deferred.reject(response)}$http=$http||$injector.get("$http"),$http(config).then(successCallback,errorCallback)}var $http,buffer=[];return{append:function(config,deferred){return buffer.push({config:config,deferred:deferred})},rejectAll:function(reason){if(reason)for(var i=0;i - <%= pkg.version %> / <%= pkg.author %> */" + }, + src: ['**/*.js', '!**/*.min.js'], + cwd: 'src', + dest: 'src', + expand: true, + ext: '.min.js', + } + }); + + grunt.loadNpmTasks('grunt-contrib-uglify'); +}; From e6d8191dc8406d663dae8b075ceca36a06e400bf Mon Sep 17 00:00:00 2001 From: Stephen Pengilley Date: Thu, 10 Nov 2016 10:11:43 +0000 Subject: [PATCH 33/42] More streamline solution to this problem --- Gruntfile.js | 23 ----------------------- package.json | 13 +++++++------ src/http-auth-interceptor.min.js | 1 - tasks/uglify.js | 20 -------------------- 4 files changed, 7 insertions(+), 50 deletions(-) delete mode 100644 Gruntfile.js delete mode 100644 src/http-auth-interceptor.min.js delete mode 100644 tasks/uglify.js diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 96d7d29..0000000 --- a/Gruntfile.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @license HTTP Auth Interceptor Module for AngularJS - * License: MIT - */ - -"use strict" - -module.exports = function(grunt) { - - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json') - }); - - grunt.loadTasks('tasks'); - - grunt.registerTask('default', function() { - grunt.log.ok("HTTP Auth Interceptor Module for AngularJS"); - grunt.log.ok("============================"); - grunt.task.run(["uglify"]); - grunt.log.ok("Minified ok"); - }); - -}; diff --git a/package.json b/package.json index d8781e7..8d3db61 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,11 @@ "auth" ], "homepage": "https://github.com/witoldsz/angular-http-auth", - "devDependencies": { - "grunt": "^0.4.5", - "grunt-contrib-uglify": "^0.11.0", - "load-grunt-config": "^0.19.1", - "time-grunt": "^1.3.0" - } + "devDependencies": { + "mkdirp": "^0.5.1", + "uglifyjs": "^2.4.10" + }, + "scripts": { + "minify": "mkdirp dist && uglifyjs src/http-auth-interceptor.js -o dist/http-auth-interceptor.min.js -c" + } } diff --git a/src/http-auth-interceptor.min.js b/src/http-auth-interceptor.min.js deleted file mode 100644 index d3de029..0000000 --- a/src/http-auth-interceptor.min.js +++ /dev/null @@ -1 +0,0 @@ -/* angular-http-auth - 1.3.0 / Witold Szczerba */!function(){"use strict";angular.module("http-auth-interceptor",["http-auth-interceptor-buffer"]).factory("authService",["$rootScope","httpBuffer",function($rootScope,httpBuffer){return{loginConfirmed:function(data,configUpdater){var updater=configUpdater||function(config){return config};$rootScope.$broadcast("event:auth-loginConfirmed",data),httpBuffer.retryAll(updater)},loginCancelled:function(data,reason){httpBuffer.rejectAll(reason),$rootScope.$broadcast("event:auth-loginCancelled",data)}}}]).config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$rootScope","$q","httpBuffer",function($rootScope,$q,httpBuffer){return{responseError:function(rejection){var config=rejection.config||{};if(!config.ignoreAuthModule)switch(rejection.status){case 401:var deferred=$q.defer(),bufferLength=httpBuffer.append(config,deferred);return 1===bufferLength&&$rootScope.$broadcast("event:auth-loginRequired",rejection),deferred.promise;case 403:$rootScope.$broadcast("event:auth-forbidden",rejection)}return $q.reject(rejection)}}}])}]),angular.module("http-auth-interceptor-buffer",[]).factory("httpBuffer",["$injector",function($injector){function retryHttpRequest(config,deferred){function successCallback(response){deferred.resolve(response)}function errorCallback(response){deferred.reject(response)}$http=$http||$injector.get("$http"),$http(config).then(successCallback,errorCallback)}var $http,buffer=[];return{append:function(config,deferred){return buffer.push({config:config,deferred:deferred})},rejectAll:function(reason){if(reason)for(var i=0;i - <%= pkg.version %> / <%= pkg.author %> */" - }, - src: ['**/*.js', '!**/*.min.js'], - cwd: 'src', - dest: 'src', - expand: true, - ext: '.min.js', - } - }); - - grunt.loadNpmTasks('grunt-contrib-uglify'); -}; From 6458076c8da6fa1c6d78d55add2e2dbb2c2bf9c2 Mon Sep 17 00:00:00 2001 From: Witold Szczerba Date: Sat, 12 Nov 2016 00:24:41 +0100 Subject: [PATCH 34/42] package.json scripts --- package.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 8d3db61..dcf467c 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,18 @@ "homepage": "https://github.com/witoldsz/angular-http-auth", "devDependencies": { "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", "uglifyjs": "^2.4.10" }, "scripts": { - "minify": "mkdirp dist && uglifyjs src/http-auth-interceptor.js -o dist/http-auth-interceptor.min.js -c" + "clean": "rimraf dist/*", + + "prebuild": "npm run clean -s && mkdirp dist", + "build": "npm run build:minify -s && npm run build:copy -s", + "build:minify": "uglifyjs src/http-auth-interceptor.js -o dist/http-auth-interceptor.min.js -c", + "build:copy": "cat src/http-auth-interceptor.js > dist/http-auth-interceptor.js", + + "version": "npm run build && git add -A dist", + "postversion": "git push && git push --tags" } } From afec65586d9e242f818c10a37aed2c724795124e Mon Sep 17 00:00:00 2001 From: Witold Szczerba Date: Sat, 12 Nov 2016 00:26:47 +0100 Subject: [PATCH 35/42] 1.4.0 --- dist/http-auth-interceptor.js | 135 ++++++++++++++++++++++++++++++ dist/http-auth-interceptor.min.js | 1 + package.json | 4 +- 3 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 dist/http-auth-interceptor.js create mode 100644 dist/http-auth-interceptor.min.js diff --git a/dist/http-auth-interceptor.js b/dist/http-auth-interceptor.js new file mode 100644 index 0000000..0fd9789 --- /dev/null +++ b/dist/http-auth-interceptor.js @@ -0,0 +1,135 @@ +/*global angular:true, browser:true */ + +/** + * @license HTTP Auth Interceptor Module for AngularJS + * (c) 2012 Witold Szczerba + * License: MIT + */ +(function () { + 'use strict'; + + angular.module('http-auth-interceptor', ['http-auth-interceptor-buffer']) + + .factory('authService', ['$rootScope','httpBuffer', function($rootScope, httpBuffer) { + return { + /** + * Call this function to indicate that authentication was successfull and trigger a + * retry of all deferred requests. + * @param data an optional argument to pass on to $broadcast which may be useful for + * example if you need to pass through details of the user that was logged in + * @param configUpdater an optional transformation function that can modify the + * requests that are retried after having logged in. This can be used for example + * to add an authentication token. It must return the request. + */ + loginConfirmed: function(data, configUpdater) { + var updater = configUpdater || function(config) {return config;}; + $rootScope.$broadcast('event:auth-loginConfirmed', data); + httpBuffer.retryAll(updater); + }, + + /** + * Call this function to indicate that authentication should not proceed. + * All deferred requests will be abandoned or rejected (if reason is provided). + * @param data an optional argument to pass on to $broadcast. + * @param reason if provided, the requests are rejected; abandoned otherwise. + */ + loginCancelled: function(data, reason) { + httpBuffer.rejectAll(reason); + $rootScope.$broadcast('event:auth-loginCancelled', data); + } + }; + }]) + + /** + * $http interceptor. + * On 401 response (without 'ignoreAuthModule' option) stores the request + * and broadcasts 'event:auth-loginRequired'. + * On 403 response (without 'ignoreAuthModule' option) discards the request + * and broadcasts 'event:auth-forbidden'. + */ + .config(['$httpProvider', function($httpProvider) { + $httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function($rootScope, $q, httpBuffer) { + return { + responseError: function(rejection) { + var config = rejection.config || {}; + if (!config.ignoreAuthModule) { + switch (rejection.status) { + case 401: + var deferred = $q.defer(); + var bufferLength = httpBuffer.append(config, deferred); + if (bufferLength === 1) + $rootScope.$broadcast('event:auth-loginRequired', rejection); + return deferred.promise; + case 403: + $rootScope.$broadcast('event:auth-forbidden', rejection); + break; + } + } + // otherwise, default behaviour + return $q.reject(rejection); + } + }; + }]); + }]); + + /** + * Private module, a utility, required internally by 'http-auth-interceptor'. + */ + angular.module('http-auth-interceptor-buffer', []) + + .factory('httpBuffer', ['$injector', function($injector) { + /** Holds all the requests, so they can be re-requested in future. */ + var buffer = []; + + /** Service initialized later because of circular dependency problem. */ + var $http; + + function retryHttpRequest(config, deferred) { + function successCallback(response) { + deferred.resolve(response); + } + function errorCallback(response) { + deferred.reject(response); + } + $http = $http || $injector.get('$http'); + $http(config).then(successCallback, errorCallback); + } + + return { + /** + * Appends HTTP request configuration object with deferred response attached to buffer. + * @return {Number} The new length of the buffer. + */ + append: function(config, deferred) { + return buffer.push({ + config: config, + deferred: deferred + }); + }, + + /** + * Abandon or reject (if reason provided) all the buffered requests. + */ + rejectAll: function(reason) { + if (reason) { + for (var i = 0; i < buffer.length; ++i) { + buffer[i].deferred.reject(reason); + } + } + buffer = []; + }, + + /** + * Retries all the buffered requests clears the buffer. + */ + retryAll: function(updater) { + for (var i = 0; i < buffer.length; ++i) { + var _cfg = updater(buffer[i].config); + if (_cfg !== false) + retryHttpRequest(_cfg, buffer[i].deferred); + } + buffer = []; + } + }; + }]); +})(); diff --git a/dist/http-auth-interceptor.min.js b/dist/http-auth-interceptor.min.js new file mode 100644 index 0000000..726bbed --- /dev/null +++ b/dist/http-auth-interceptor.min.js @@ -0,0 +1 @@ +!function(){"use strict";angular.module("http-auth-interceptor",["http-auth-interceptor-buffer"]).factory("authService",["$rootScope","httpBuffer",function($rootScope,httpBuffer){return{loginConfirmed:function(data,configUpdater){var updater=configUpdater||function(config){return config};$rootScope.$broadcast("event:auth-loginConfirmed",data),httpBuffer.retryAll(updater)},loginCancelled:function(data,reason){httpBuffer.rejectAll(reason),$rootScope.$broadcast("event:auth-loginCancelled",data)}}}]).config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$rootScope","$q","httpBuffer",function($rootScope,$q,httpBuffer){return{responseError:function(rejection){var config=rejection.config||{};if(!config.ignoreAuthModule)switch(rejection.status){case 401:var deferred=$q.defer(),bufferLength=httpBuffer.append(config,deferred);return 1===bufferLength&&$rootScope.$broadcast("event:auth-loginRequired",rejection),deferred.promise;case 403:$rootScope.$broadcast("event:auth-forbidden",rejection)}return $q.reject(rejection)}}}])}]),angular.module("http-auth-interceptor-buffer",[]).factory("httpBuffer",["$injector",function($injector){function retryHttpRequest(config,deferred){function successCallback(response){deferred.resolve(response)}function errorCallback(response){deferred.reject(response)}$http=$http||$injector.get("$http"),$http(config).then(successCallback,errorCallback)}var $http,buffer=[];return{append:function(config,deferred){return buffer.push({config:config,deferred:deferred})},rejectAll:function(reason){if(reason)for(var i=0;i dist/http-auth-interceptor.js", - "version": "npm run build && git add -A dist", "postversion": "git push && git push --tags" } From 39e0a059bc32fa612e3822072b4c06f08f40a2ea Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Sat, 12 Nov 2016 12:08:42 +0200 Subject: [PATCH 36/42] Add license key to bower.json #137 --- bower.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 27daaaf..54fac45 100644 --- a/bower.json +++ b/bower.json @@ -12,5 +12,6 @@ }, "ignore": [ "package.json" - ] + ], + "license": "MIT" } From af257667c273333cca377cc4688aff42c9174afc Mon Sep 17 00:00:00 2001 From: Witold Szczerba Date: Sat, 12 Nov 2016 13:13:46 +0100 Subject: [PATCH 37/42] 1.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef56b2e..30affc7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-http-auth", - "version": "1.4.0", + "version": "1.4.1", "description": "HTTP Auth Interceptor Module for AngularJS.", "main": "src/http-auth-interceptor.js", "repository": { From 86e94f6a1c9f1adc92f9089779926b4a45343fdf Mon Sep 17 00:00:00 2001 From: Michael Fladischer Date: Tue, 23 Feb 2016 20:01:06 +0100 Subject: [PATCH 38/42] Add support for CommonJS loading. Now that angular has CommonJS support it would be nice to have this too. --- src/http-auth-interceptor.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index 0fd9789..060d8f8 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -5,6 +5,7 @@ * (c) 2012 Witold Szczerba * License: MIT */ + (function () { 'use strict'; @@ -133,3 +134,8 @@ }; }]); })(); + +/* commonjs package manager support (eg componentjs) */ +if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports){ + module.exports = 'http-auth-interceptor'; +} From fc131b5a0d122c31e2bd77edd28a39b2fac5c1d5 Mon Sep 17 00:00:00 2001 From: Witold Szczerba Date: Thu, 17 Nov 2016 16:20:51 +0100 Subject: [PATCH 39/42] 1.5.0 --- dist/http-auth-interceptor.js | 6 ++++++ dist/http-auth-interceptor.min.js | 2 +- package.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/dist/http-auth-interceptor.js b/dist/http-auth-interceptor.js index 0fd9789..060d8f8 100644 --- a/dist/http-auth-interceptor.js +++ b/dist/http-auth-interceptor.js @@ -5,6 +5,7 @@ * (c) 2012 Witold Szczerba * License: MIT */ + (function () { 'use strict'; @@ -133,3 +134,8 @@ }; }]); })(); + +/* commonjs package manager support (eg componentjs) */ +if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports){ + module.exports = 'http-auth-interceptor'; +} diff --git a/dist/http-auth-interceptor.min.js b/dist/http-auth-interceptor.min.js index 726bbed..167529a 100644 --- a/dist/http-auth-interceptor.min.js +++ b/dist/http-auth-interceptor.min.js @@ -1 +1 @@ -!function(){"use strict";angular.module("http-auth-interceptor",["http-auth-interceptor-buffer"]).factory("authService",["$rootScope","httpBuffer",function($rootScope,httpBuffer){return{loginConfirmed:function(data,configUpdater){var updater=configUpdater||function(config){return config};$rootScope.$broadcast("event:auth-loginConfirmed",data),httpBuffer.retryAll(updater)},loginCancelled:function(data,reason){httpBuffer.rejectAll(reason),$rootScope.$broadcast("event:auth-loginCancelled",data)}}}]).config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$rootScope","$q","httpBuffer",function($rootScope,$q,httpBuffer){return{responseError:function(rejection){var config=rejection.config||{};if(!config.ignoreAuthModule)switch(rejection.status){case 401:var deferred=$q.defer(),bufferLength=httpBuffer.append(config,deferred);return 1===bufferLength&&$rootScope.$broadcast("event:auth-loginRequired",rejection),deferred.promise;case 403:$rootScope.$broadcast("event:auth-forbidden",rejection)}return $q.reject(rejection)}}}])}]),angular.module("http-auth-interceptor-buffer",[]).factory("httpBuffer",["$injector",function($injector){function retryHttpRequest(config,deferred){function successCallback(response){deferred.resolve(response)}function errorCallback(response){deferred.reject(response)}$http=$http||$injector.get("$http"),$http(config).then(successCallback,errorCallback)}var $http,buffer=[];return{append:function(config,deferred){return buffer.push({config:config,deferred:deferred})},rejectAll:function(reason){if(reason)for(var i=0;i Date: Sun, 5 Mar 2017 19:24:38 +0530 Subject: [PATCH 40/42] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52fdb11..15bf2bc 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ The `loginConfirmed` method supports the injection of an Updater function that w authService.loginConfirmed([data], [Updater-Function]) //application of tokens to previously fired requests: - var token = reponse.token; + var token = response.token; authService.loginConfirmed('success', function(config){ config.headers["Authorization"] = token; From cc316e352083d8e0f3e72e7171a1e41743fabf4c Mon Sep 17 00:00:00 2001 From: Peter Neave Date: Tue, 21 Mar 2017 09:20:13 +1100 Subject: [PATCH 41/42] Fix minor spelling mistake --- dist/http-auth-interceptor.js | 2 +- src/http-auth-interceptor.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/http-auth-interceptor.js b/dist/http-auth-interceptor.js index 060d8f8..3cff6cc 100644 --- a/dist/http-auth-interceptor.js +++ b/dist/http-auth-interceptor.js @@ -14,7 +14,7 @@ .factory('authService', ['$rootScope','httpBuffer', function($rootScope, httpBuffer) { return { /** - * Call this function to indicate that authentication was successfull and trigger a + * Call this function to indicate that authentication was successful and trigger a * retry of all deferred requests. * @param data an optional argument to pass on to $broadcast which may be useful for * example if you need to pass through details of the user that was logged in diff --git a/src/http-auth-interceptor.js b/src/http-auth-interceptor.js index 060d8f8..3cff6cc 100644 --- a/src/http-auth-interceptor.js +++ b/src/http-auth-interceptor.js @@ -14,7 +14,7 @@ .factory('authService', ['$rootScope','httpBuffer', function($rootScope, httpBuffer) { return { /** - * Call this function to indicate that authentication was successfull and trigger a + * Call this function to indicate that authentication was successful and trigger a * retry of all deferred requests. * @param data an optional argument to pass on to $broadcast which may be useful for * example if you need to pass through details of the user that was logged in From aa2456d3cd40a32c673b05dbcd0a6ee13c9ee4d7 Mon Sep 17 00:00:00 2001 From: Viktor Lieskovsky Date: Tue, 3 Oct 2017 17:51:56 +0200 Subject: [PATCH 42/42] fix formatting of README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 15bf2bc..ad36219 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ the `event:auth-forbidden` message is broadcast from $rootScope. Sometimes you might not want the interceptor to intercept a request even if one returns 401 or 403. In a case like this you can add `ignoreAuthModule: true` to the request config. A common use case for this would be, for example, a login request which returns 401 if the login credentials are invalid. -###Typical use case: +### Typical use case: * somewhere (some service or controller) the: `$http(...).then(function(response) { do-something-with-response })` is invoked, * the response of that requests is a **HTTP 401**, @@ -63,9 +63,9 @@ Sometimes you might not want the interceptor to intercept a request even if one the `function(response) {do-something-with-response}` will fire, * your application will continue as nothing had happened. -###Advanced use case: +### Advanced use case: -####Sending data to listeners: +#### Sending data to listeners: You can supply additional data to observers across your application who are listening for `event:auth-loginConfirmed` and `event:auth-loginCancelled`: $scope.$on('event:auth-loginConfirmed', function(event, data){ @@ -80,7 +80,7 @@ You can supply additional data to observers across your application who are list Use the `authService.loginConfirmed([data])` and `authService.loginCancelled([data])` methods to emit data with your login and logout events. -####Updating [$http(config)](https://docs.angularjs.org/api/ng/service/$http): +#### Updating [$http(config)](https://docs.angularjs.org/api/ng/service/$http): Successful login means that the previous request are ready to be fired again, however now that login has occurred certain aspects of the previous requests might need to be modified on the fly. This is particularly important in a token based authentication scheme where an authorization token should be added to the header. The `loginConfirmed` method supports the injection of an Updater function that will apply changes to the http config object.