Skip to content

Commit 90d03ec

Browse files
author
Domagoj Rukavina
committed
Added callback isResponseUnauthorized to config
- allows external function to specify whether response should be considered unauthorized
1 parent f3b9340 commit 90d03ec

File tree

5 files changed

+38
-11
lines changed

5 files changed

+38
-11
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ config: {
4343
// When set, response which invalidates token will be resolved after the token has been renewed
4444
// in effect, token will be loaded in sync with response, otherwise renew will run async to response
4545
shouldWaitForTokenRenewal: boolean,
46+
47+
// Checks if response should be considered unauthorized (by default only 401 responses are
48+
// considered unauthorized). Override this method if you need to trigger token renewal for
49+
// other response statuses.
50+
isResponseUnauthorized: (response) => boolean,
4651
4752
// (Required) Adds authorization for intercepted requests
4853
authorizeRequest: (request, accessToken) => authorizedRequest,

src/AccessTokenProvider.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
import {
2-
isResponseUnauthorized,
3-
} from './services/http';
4-
51
/**
62
* Provides a way for renewing access token with correct refresh token. It will automatically
73
* dispatch a call to server with request provided via config. It also ensures that
@@ -39,7 +35,6 @@ export default class AccessTokenProvider {
3935
renew() {
4036
// if token resolver is not authorized it should just resolve
4137
if (!this.isAuthorized()) {
42-
console.warn('Please authorize provider before renewing or check shouldIntercept config.');
4338
return Promise.resolve();
4439
}
4540

@@ -89,7 +84,7 @@ export default class AccessTokenProvider {
8984
handleFetchAccessTokenResponse(response) {
9085
this.renewAccessTokenPromise = null;
9186

92-
if (isResponseUnauthorized(response)) {
87+
if (this.config.isResponseUnauthorized(response)) {
9388
this.clear();
9489
return null;
9590
}

src/FetchInterceptor.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import {
22
ERROR_INVALID_CONFIG,
33
} from './const';
4-
import {
5-
isResponseUnauthorized,
6-
} from './services/http';
4+
import * as http from './services/http';
75
import TokenExpiredException from './services/TokenExpiredException';
86
import RetryCountExceededException from './services/RetryCountExceededException';
97
import AccessTokenProvider from './AccessTokenProvider';
@@ -22,6 +20,7 @@ export default class FetchInterceptor {
2220
createAccessTokenRequest: null,
2321
shouldIntercept: () => true,
2422
shouldInvalidateAccessToken: () => false,
23+
isResponseUnauthorized: http.isResponseUnauthorized,
2524
parseAccessToken: null,
2625
authorizeRequest: null,
2726
onAccessTokenChange: null,
@@ -66,6 +65,11 @@ export default class FetchInterceptor {
6665
* (Required) Adds authorization for intercepted requests
6766
* authorizeRequest: (request, accessToken) => authorizedRequest,
6867
*
68+
* Checks if response should be considered unauthorized (by default only 401 responses are
69+
* considered unauthorized. Override this method if you need to trigger token renewal for
70+
* other response statuses.
71+
* isResponseUnauthorized: (response) => boolean,
72+
*
6973
* Number of retries after initial request was unauthorized
7074
* fetchRetryCount: 1,
7175
*
@@ -311,6 +315,7 @@ export default class FetchInterceptor {
311315

312316
handleResponse(requestContext) {
313317
const { shouldIntercept, response, fetchResolve, fetchReject } = requestContext;
318+
const { isResponseUnauthorized } = this.config;
314319

315320
// can only be empty on network errors
316321
if (!response) {

test/fetchInterceptor.spec.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const configuration = config => ({
2424
},
2525
onAccessTokenChange: null,
2626
onResponse: null,
27+
isResponseUnauthorized: response => response.status === 401,
2728
...config,
2829
});
2930

@@ -410,6 +411,26 @@ describe('fetch-intercept', function () {
410411
done(error);
411412
});
412413
});
414+
415+
it('should fetch successfully with access token expired and status 403', function (done) {
416+
fetchInterceptor.configure(configuration({
417+
isResponseUnauthorized: (response) => response.status === 403
418+
}));
419+
// set expired access token
420+
fetchInterceptor.authorize('refresh_token', 'token1');
421+
422+
fetch('http://localhost:5000/401/1?respondStatus=403').then(response => {
423+
expect(response.status).to.be.equal(200);
424+
return response.json();
425+
})
426+
.then(data => {
427+
expect(data.value).to.be.equal('1');
428+
done();
429+
})
430+
.catch(error => {
431+
done(error);
432+
});
433+
});
413434
});
414435

415436
describe('refresh token is invalid', () => {

test/helpers/server.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@ app.get('/200', function(req, res) {
1616
function handleUnauthorizedRequest(req, res ){
1717
const response = () => {
1818
const token = req.header('authorization') && req.header('authorization').split(' ')[1];
19+
const responseStatus = req.query.respondStatus || 401;
1920

2021
if (token === EXPIRED_TOKEN) {
21-
res.status(401).send();
22+
res.status(responseStatus).send();
2223
} else if (token === VALID_TOKEN) {
2324
if (req.query.invalidate){
2425
res.set('invalidates-token', true);
2526
}
2627

2728
res.json({ 'value': req.params.id });
2829
} else {
29-
res.status(401).send();
30+
res.status(responseStatus).send();
3031
}
3132
};
3233

0 commit comments

Comments
 (0)