Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@shoutem/fetch-token-intercept

Package Overview
Dependencies
Maintainers
4
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@shoutem/fetch-token-intercept - npm Package Compare versions

Comparing version 0.2.2 to 0.3.0

12

lib/AccessTokenProvider.js

@@ -47,3 +47,3 @@ "use strict";

/**
* Renews current access token with provided refresh token
* Configures access token provider
*/

@@ -53,2 +53,12 @@

_createClass(AccessTokenProvider, [{
key: "configure",
value: function configure(config) {
this.config = _extends({}, this.config, config);
}
/**
* Renews current access token with provided refresh token
*/
}, {
key: "renew",

@@ -55,0 +65,0 @@ value: function renew() {

158

lib/FetchInterceptor.js

@@ -13,2 +13,6 @@ 'use strict';

var _isFunction = require('lodash/isFunction');
var _isFunction2 = _interopRequireDefault(_isFunction);
var _const = require('./const');

@@ -32,6 +36,6 @@

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

@@ -42,5 +46,65 @@

/**
* Prepares signed request object which can be used for renewing access token
*
* @callback createAccessTokenRequest
* @param {string} refreshToken Refresh token used to sign the request
* @returns {Request} Signed request object which can be used to get access token
*/
/**
* Parses access token from access token response object
*
* @callback parseAccessToken
* @param {Response} response Response object with access token
* @returns {string} Access token parsed from response
*/
/**
* Checks whether interceptor will intercept this request or just let it pass through
*
* @callback shouldIntercept
* @param {Request} request Request object
* @returns {bool} A value indicating whether this request should be intercepted
*/
/**
* Checks whether provided response invalidates current access token
*
* @callback shouldInvalidateAccessToken
* @param {Response} response Response object
* @returns {bool} A value indicating whether token should be invalidated
*/
/**
* Adds authorization for intercepted requests
*
* @callback authorizeRequest
* @param {Request} request Request object being intercepted
* @param {string} accessToken Current access token
* @returns {Request} Authorized request object
*/
var getDefaultConfig = function getDefaultConfig() {
return {
fetchRetryCount: 1,
createAccessTokenRequest: null,
shouldIntercept: function shouldIntercept() {
return false;
},
shouldInvalidateAccessToken: function shouldInvalidateAccessToken() {
return false;
},
isResponseUnauthorized: http.isResponseUnauthorized,
parseAccessToken: null,
authorizeRequest: null,
onAccessTokenChange: null,
onResponse: null
};
};
/**
* Provides a default implementation for intercepting fetch requests. It will try to resolve
* unauthorized responses by renewing the access token and repeating the initial request.
*/
var FetchInterceptor = function () {

@@ -52,18 +116,5 @@ function FetchInterceptor(fetch) {

this.fetch = fetch;
this.accessTokenProvider = new _AccessTokenProvider2.default(this.fetch);
this.config = {
fetchRetryCount: 1,
createAccessTokenRequest: null,
shouldIntercept: function shouldIntercept() {
return true;
},
shouldInvalidateAccessToken: function shouldInvalidateAccessToken() {
return false;
},
isResponseUnauthorized: http.isResponseUnauthorized,
parseAccessToken: null,
authorizeRequest: null,
onAccessTokenChange: null,
onResponse: null
};
this.config = getDefaultConfig();

@@ -91,33 +142,24 @@ this.intercept = this.intercept.bind(this);

*
* @param config
*
* (Required) Prepare fetch request for renewing new access token
* createAccessTokenRequest: (refreshToken) => request,
*
* (Required) Parses access token from access token response
* parseAccessToken: (response) => accessToken,
*
* (Required) Defines whether interceptor will intercept this request or just let it pass through
* shouldIntercept: (request) => boolean,
*
* (Required) Defines whether access token will be invalidated after this response
* shouldInvalidateAccessToken: (response) => boolean,
*
* (Required) Adds authorization for intercepted requests
* authorizeRequest: (request, accessToken) => authorizedRequest,
*
* Checks if response should be considered unauthorized (by default only 401 responses are
* considered unauthorized. Override this method if you need to trigger token renewal for
* other response statuses.
* isResponseUnauthorized: (response) => boolean,
*
* Number of retries after initial request was unauthorized
* fetchRetryCount: 1,
*
* Event invoked when access token has changed
* onAccessTokenChange: null,
*
* Event invoked when response is resolved
* onResponse: null,
*
* @param {object} config
* @param {createAccessTokenRequest} config.createAccessTokenRequest
* Prepare fetch request for renewing new access token
* @param {parseAccessToken} config.parseAccessToken
* Parses access token from access token response
* @param {shouldIntercept} config.shouldIntercept
* Defines whether interceptor will intercept this request or just let it pass through
* @param {shouldInvalidateAccessToken} config.shouldInvalidateAccessToken
* Defines whether access token will be invalidated after this response
* @param {authorizeRequest} config.authorizeRequest
* Adds authorization for intercepted requests
* @param {function} [config.isResponseUnauthorized=null]
* Checks if response should be considered unauthorized (by default only 401 responses are
* considered unauthorized. Override this method if you need to trigger token renewal for
* other response statuses.
* @param {number} [config.fetchRetryCount=1]
* Number of retries after initial request was unauthorized
* @param {number} [config.onAccessTokenChange=null]
* Event invoked when access token has changed
* @param {number} [config.onResponse=null]
* Event invoked when response is resolved
* </pre>
*/

@@ -135,3 +177,3 @@

this.accessTokenProvider = new _AccessTokenProvider2.default(this.fetch, this.config);
this.accessTokenProvider.configure(this.config);
}

@@ -141,4 +183,4 @@

* Authorizes fetch interceptor with given refresh token
* @param refreshToken
* @param accessToken
* @param {string} refreshToken Refresh token
* @param {string} accessToken Access token
*/

@@ -174,2 +216,14 @@

/**
* Clears current authorization and restores default configuration, e.g. interceptor
* will stop intercepting requests.
*/
}, {
key: 'unload',
value: function unload() {
this.clear();
this.config = getDefaultConfig();
}
/**
* Main intercept method, you should chain this inside wrapped fetch call

@@ -196,3 +250,3 @@ * @param args Args initially provided to fetch method

value: function isConfigValid() {
return this.config.shouldIntercept && this.config.authorizeRequest && this.config.createAccessTokenRequest && this.config.parseAccessToken;
return this.config.shouldIntercept && (0, _isFunction2.default)(this.config.shouldIntercept) && this.config.authorizeRequest && (0, _isFunction2.default)(this.config.authorizeRequest) && this.config.isResponseUnauthorized && (0, _isFunction2.default)(this.config.isResponseUnauthorized) && this.config.createAccessTokenRequest && (0, _isFunction2.default)(this.config.createAccessTokenRequest) && this.config.parseAccessToken && (0, _isFunction2.default)(this.config.parseAccessToken);
}

@@ -199,0 +253,0 @@ }, {

@@ -12,2 +12,4 @@ 'use strict';

exports.clear = clear;
exports.isActive = isActive;
exports.unload = unload;

@@ -25,2 +27,3 @@ var _environment = require('./services/environment');

var interceptor = null;
var environment = null;

@@ -52,20 +55,29 @@ function attach(env) {

function init() {
if ((0, _environment.isReactNative)()) {
attach(global);
} else if ((0, _environment.isWorker)()) {
attach(self);
} else if ((0, _environment.isWeb)()) {
attach(window);
} else if ((0, _environment.isNode)()) {
attach(global);
} else {
function initialize() {
environment = (0, _environment.resolveEnvironment)();
if (!environment) {
throw new Error('Unsupported environment for fetch-token-intercept');
}
attach(environment);
}
/**
* Initializes and configures interceptor
* @param config Configuration object
* @see FetchInterceptor#configure
*/
function configure(config) {
if (!interceptor) {
initialize();
}
interceptor.configure(config);
}
/**
* Initializes tokens which will be used by interceptor
* @param args
* @see FetchInterceptor#authorize
*/
function authorize() {

@@ -77,2 +89,6 @@ var _interceptor2;

/**
* Returns current set of tokens used by interceptor
* @returns {{accessToken: string, refreshToken: string}|*}
*/
function getAuthorization() {

@@ -82,2 +98,5 @@ return interceptor.getAuthorization();

/**
* Clears authorization tokens from interceptor
*/
function clear() {

@@ -87,5 +106,22 @@ return interceptor.clear();

/**
* Gets a value indicating whether interceptor is currently active
* @returns {boolean}
*/
function isActive() {
return !!interceptor;
}
/**
* Removes interceptor and restores default behaviour
*/
function unload() {
if (interceptor) {
interceptor.unload();
}
}
exports.isResponseUnauthorized = _http.isResponseUnauthorized;
init();
initialize();

@@ -13,2 +13,3 @@ 'use strict';

exports.isWorker = isWorker;
exports.resolveEnvironment = resolveEnvironment;
// Uses Emscripten stategy for determining environment

@@ -29,2 +30,19 @@ function isReactNative() {

return typeof importScripts === 'function';
}
function resolveEnvironment() {
if (isReactNative()) {
return global;
}
if (isWorker()) {
return self;
}
if (isWeb()) {
return window;
}
if (isNode()) {
return global;
}
return null;
}

@@ -11,2 +11,8 @@ "use strict";

/**
* Checks if response status matches the provided status
* @param response Response object
* @param status Query status
* @returns {boolean} Value indicating whether response status matches query status
*/
function isResponseStatus(response, status) {

@@ -13,0 +19,0 @@ if (!response) {

@@ -1,2 +0,2 @@

"use strict";
'use strict';

@@ -50,3 +50,3 @@ Object.defineProperty(exports, "__esModule", {

// Use V8's native method if available, otherwise fallback
if ("captureStackTrace" in Error) {
if ('captureStackTrace' in Error) {
Error.captureStackTrace(_this, RetryCountExceededException);

@@ -53,0 +53,0 @@ } else {

@@ -1,2 +0,2 @@

"use strict";
'use strict';

@@ -50,3 +50,3 @@ Object.defineProperty(exports, "__esModule", {

// Use V8's native method if available, otherwise fallback
if ("captureStackTrace" in Error) {
if ('captureStackTrace' in Error) {
Error.captureStackTrace(_this, TokenExpiredException);

@@ -53,0 +53,0 @@ } else {

{
"name": "@shoutem/fetch-token-intercept",
"version": "0.2.2",
"version": "0.3.0",
"description": "Fetch interceptor for managing refresh token flow.",

@@ -60,3 +60,5 @@ "main": "lib/index.js",

},
"dependencies": {}
"dependencies": {
"lodash": "^4.17.4"
}
}

@@ -72,4 +72,4 @@ [![CircleCI](https://img.shields.io/circleci/project/github/shoutem/fetch-token-intercept.svg)](https://github.com/shoutem/fetch-token-intercept)

All required methods return a promise to enable reading of request or response body.
You should avoid reading the body directly on provided requests and responses and instead clone
them first. The library does not clone objects to avoid unnecessary overhead in cases where
You should avoid reading the body directly on provided requests and responses and instead **clone
them first.** The library does not clone objects to avoid unnecessary overhead in cases where
reading a body is not required to provide data.

@@ -121,2 +121,6 @@

`unload()`
Completely unloads the library and restores initial state.
`isResponseUnauthorized(response)`

@@ -123,0 +127,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc