fetch-mw-oauth2
Advanced tools
Comparing version 1.0.0 to 1.0.1
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.fetchMwOAuth2=t():e.fetchMwOAuth2=t()}(self,(function(){return(()=>{"use strict";var e={681:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.encode=void 0,t.encode=function(e){return btoa(e)}},443:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0});class r extends Error{constructor(e,t,r){super(e),this.oauth2Code=t,this.httpCode=r}}t.default=r},13:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=r(882);t.default=class{constructor(e,t=null){if(!e.grantType&&!t&&!e.accessToken)throw new Error("If no grantType is specified, a token must be provided");this.options=e,e.accessToken&&(console.warn("[fetch-mw-oauth2] Specifying accessToken via the options argument in the constructor of OAuth2 is deprecated. Please supply the options in the second argument. Backwards compatability will be removed in a future version of this library"),t={accessToken:e.accessToken,refreshToken:e.refreshToken||null,expiresAt:null}),this.token=t,this.activeRefresh=null,this.refreshTimer=null,this.scheduleRefresh()}async fetch(e,t){const r=new Request(e,t);return this.fetchMw(r,(e=>fetch(e)))}async fetchMw(e,t){const r=await this.getAccessToken();let n=e.clone();n.headers.set("Authorization","Bearer "+r);let o=await t(n);if(!o.ok&&401===o.status){const r=await this.refreshToken();n=e.clone(),n.headers.set("Authorization","Bearer "+r.accessToken),o=await t(n)}return o}async getToken(){return this.token&&(null===this.token.expiresAt||this.token.expiresAt>Date.now())?this.token:this.refreshToken()}async getAccessToken(){return(await this.getToken()).accessToken}async refreshToken(){if(this.activeRefresh)return this.activeRefresh;this.activeRefresh=(0,n.refreshToken)(this.options,this.token);try{const e=await this.activeRefresh;return this.token=e,this.scheduleRefresh(),e}catch(e){throw this.options.onAuthError&&this.options.onAuthError(e),e}finally{this.activeRefresh=null}}scheduleRefresh(){if(this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null),!this.token||!this.token.expiresAt||!this.token.refreshToken)return;const e=this.token.expiresAt-Date.now();e<12e4||(this.refreshTimer=setTimeout((async()=>{try{await this.refreshToken()}catch(e){console.error("[fetch-mw-oauth2] error while doing a background OAuth2 auto-refresh",e)}}),e-6e4))}}},882:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.refreshToken=t.objToQueryString=void 0;const n=r(681),o=r(443);function s(e){return Object.entries(e).map((([e,t])=>void 0===t?"":encodeURIComponent(e)+"="+encodeURIComponent(t))).join("&")}t.objToQueryString=s,t.refreshToken=async function e(t,r){let i;const c=r;if(null==c?void 0:c.refreshToken)i={grant_type:"refresh_token",refresh_token:c.refreshToken},void 0===t.clientSecret&&(i.client_id=t.clientId);else switch(t.grantType){case"client_credentials":i={grant_type:"client_credentials"},t.scope&&(i.scope=t.scope.join(" "));break;case"password":i={grant_type:"password",username:t.userName,password:t.password},t.scope&&(i.scope=t.scope.join(" "));break;case"authorization_code":i={grant_type:"authorization_code",code:t.code,redirect_uri:t.redirectUri,client_id:t.clientId,code_verifier:t.codeVerifier};break;default:throw"string"==typeof t.grantType?new Error("Unknown grantType: "+t.grantType):new Error('Cannot obtain an access token if no "grantType" is specified')}const a={"Content-Type":"application/x-www-form-urlencoded"};let h=!1;if(void 0!==t.clientSecret){h=!0;const e=(0,n.encode)(t.clientId+":"+t.clientSecret);a.Authorization="Basic "+e}const u=await fetch(t.tokenEndpoint,{method:"POST",headers:a,body:s(i)}),f=await u.json();if(!u.ok){if("refresh_token"===i.grant_type&&t.grantType)return e(t,null);const r=u.status;let n,s;throw f.error?(n="OAuth2 error "+f.error+".",f.error_description&&(n+=" "+f.error_description),s=f.error):(n="HTTP Error "+u.status+" "+u.statusText,401===u.status&&h&&(n+=". It's likely that the clientId and/or clientSecret was incorrect"),s=null),new o.default(n,s,r)}const l={accessToken:f.access_token,expiresAt:f.expires_in?Date.now()+1e3*f.expires_in:null,refreshToken:f.refresh_token?f.refresh_token:null};return t.onTokenUpdate&&t.onTokenUpdate(l),l}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}var n={};return(()=>{var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.OAuth2Error=e.OAuth2=e.fetchMwOAuth2=e.default=void 0;var t=r(13);Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"fetchMwOAuth2",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"OAuth2",{enumerable:!0,get:function(){return t.default}});var o=r(443);Object.defineProperty(e,"OAuth2Error",{enumerable:!0,get:function(){return o.default}})})(),n})()})); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.fetchMwOAuth2=t():e.fetchMwOAuth2=t()}(self,(()=>(()=>{"use strict";var e={681:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.encode=void 0,t.encode=function(e){return btoa(e)}},443:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0});class r extends Error{constructor(e,t,r){super(e),this.oauth2Code=t,this.httpCode=r}}t.default=r},13:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=r(882);t.default=class{constructor(e,t=null){if(!e.grantType&&!t&&!e.accessToken)throw new Error("If no grantType is specified, a token must be provided");this.options=e,e.accessToken&&(console.warn("[fetch-mw-oauth2] Specifying accessToken via the options argument in the constructor of OAuth2 is deprecated. Please supply the options in the second argument. Backwards compatability will be removed in a future version of this library"),t={accessToken:e.accessToken,refreshToken:e.refreshToken||null,expiresAt:null}),this.token=t,this.activeRefresh=null,this.refreshTimer=null,this.scheduleRefresh()}async fetch(e,t){const r=new Request(e,t);return this.fetchMw(r,(e=>fetch(e)))}async fetchMw(e,t){const r=await this.getAccessToken();let n=e.clone();n.headers.set("Authorization","Bearer "+r);let o=await t(n);if(!o.ok&&401===o.status){const r=await this.refreshToken();n=e.clone(),n.headers.set("Authorization","Bearer "+r.accessToken),o=await t(n)}return o}async getToken(){return this.token&&(null===this.token.expiresAt||this.token.expiresAt>Date.now())?this.token:this.refreshToken()}async getAccessToken(){return(await this.getToken()).accessToken}async refreshToken(){if(this.activeRefresh)return this.activeRefresh;this.activeRefresh=(0,n.refreshToken)(this.options,this.token);try{const e=await this.activeRefresh;return this.token=e,this.scheduleRefresh(),e}catch(e){throw this.options.onAuthError&&this.options.onAuthError(e),e}finally{this.activeRefresh=null}}scheduleRefresh(){if(this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null),!this.token||!this.token.expiresAt||!this.token.refreshToken)return;const e=this.token.expiresAt-Date.now();e<12e4||(this.refreshTimer=setTimeout((async()=>{try{await this.refreshToken()}catch(e){console.error("[fetch-mw-oauth2] error while doing a background OAuth2 auto-refresh",e)}}),e-6e4))}}},882:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.refreshToken=t.objToQueryString=void 0;const n=r(681),o=r(443);function s(e){return Object.entries(e).map((([e,t])=>void 0===t?"":encodeURIComponent(e)+"="+encodeURIComponent(t))).join("&")}t.objToQueryString=s,t.refreshToken=async function e(t,r){let i;const c=r;if(null==c?void 0:c.refreshToken)i={grant_type:"refresh_token",refresh_token:c.refreshToken},void 0===t.clientSecret&&(i.client_id=t.clientId);else switch(t.grantType){case"client_credentials":i={grant_type:"client_credentials"},t.scope&&(i.scope=t.scope.join(" "));break;case"password":i={grant_type:"password",username:t.userName,password:t.password},t.scope&&(i.scope=t.scope.join(" "));break;case"authorization_code":i={grant_type:"authorization_code",code:t.code,redirect_uri:t.redirectUri,client_id:t.clientId,code_verifier:t.codeVerifier};break;default:throw"string"==typeof t.grantType?new Error("Unknown grantType: "+t.grantType):new Error('Cannot obtain an access token if no "grantType" is specified')}const a={"Content-Type":"application/x-www-form-urlencoded"};let h=!1;if(void 0!==t.clientSecret){h=!0;const e=(0,n.encode)(t.clientId+":"+t.clientSecret);a.Authorization="Basic "+e}const u=await fetch(t.tokenEndpoint,{method:"POST",headers:a,body:s(i)}),f=await u.json();if(!u.ok){if("refresh_token"===i.grant_type&&t.grantType)return e(t,null);const r=u.status;let n,s;throw f.error?(n="OAuth2 error "+f.error+".",f.error_description&&(n+=" "+f.error_description),s=f.error):(n="HTTP Error "+u.status+" "+u.statusText,401===u.status&&h&&(n+=". It's likely that the clientId and/or clientSecret was incorrect"),s=null),new o.default(n,s,r)}const l={accessToken:f.access_token,expiresAt:f.expires_in?Date.now()+1e3*f.expires_in:null,refreshToken:f.refresh_token?f.refresh_token:null};return t.onTokenUpdate&&t.onTokenUpdate(l),l}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}var n={};return(()=>{var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.OAuth2Error=e.OAuth2=e.fetchMwOAuth2=e.default=void 0;var t=r(13);Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"fetchMwOAuth2",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"OAuth2",{enumerable:!0,get:function(){return t.default}});var o=r(443);Object.defineProperty(e,"OAuth2Error",{enumerable:!0,get:function(){return o.default}})})(),n})())); | ||
//# sourceMappingURL=fetch-mw-oauth2.min.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.OAuth2Error = void 0; | ||
/** | ||
@@ -15,3 +16,3 @@ * An error class for any error the server emits. | ||
*/ | ||
class OAuthError extends Error { | ||
class OAuth2Error extends Error { | ||
constructor(message, oauth2Code, httpCode) { | ||
@@ -23,3 +24,3 @@ super(message); | ||
} | ||
exports.default = OAuthError; | ||
exports.OAuth2Error = OAuth2Error; | ||
//# sourceMappingURL=error.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const util_1 = require("./util"); | ||
class OAuth2 { | ||
constructor(options, token = null) { | ||
if (!options.grantType && !token && !options.accessToken) { | ||
throw new Error('If no grantType is specified, a token must be provided'); | ||
} | ||
exports.OAuth2Fetch = void 0; | ||
class OAuth2Fetch { | ||
constructor(options) { | ||
/** | ||
* Current active token (if any) | ||
*/ | ||
this.token = null; | ||
/** | ||
* Keeping track of an active refreshToken operation. | ||
* | ||
* This will allow us to ensure only 1 such operation happens at any | ||
* given time. | ||
*/ | ||
this.activeRefresh = null; | ||
/** | ||
* Timer trigger for the next automated refresh | ||
*/ | ||
this.refreshTimer = null; | ||
this.options = options; | ||
// Backwards compatibility | ||
if (options.accessToken) { | ||
// eslint-disable-next-line no-console | ||
console.warn('[fetch-mw-oauth2] Specifying accessToken via the options argument ' + | ||
'in the constructor of OAuth2 is deprecated. Please supply the ' + | ||
'options in the second argument. Backwards compatability will be ' + | ||
'removed in a future version of this library'); | ||
token = { | ||
accessToken: options.accessToken, | ||
refreshToken: options.refreshToken || null, | ||
expiresAt: null, | ||
}; | ||
if (options.getStoredToken) { | ||
(async () => { | ||
this.token = await options.getStoredToken(); | ||
})(); | ||
} | ||
this.token = token; | ||
this.activeRefresh = null; | ||
this.refreshTimer = null; | ||
this.scheduleRefresh(); | ||
@@ -33,3 +34,3 @@ } | ||
* first. If the access token is almost expiring, this function might attempt | ||
* to refresh it. | ||
1G* to refresh it. | ||
*/ | ||
@@ -40,3 +41,3 @@ async fetch(input, init) { | ||
const request = new Request(input, init); | ||
return this.fetchMw(request, req => fetch(req)); | ||
return this.mw()(request, req => fetch(req)); | ||
} | ||
@@ -47,17 +48,20 @@ /** | ||
* | ||
* The function takes a Request object, and a next() function that | ||
* represents the next 'fetch' function in the chain. | ||
* This function returns a middleware function with the signature | ||
* (request, next): Response | ||
*/ | ||
async fetchMw(request, next) { | ||
const accessToken = await this.getAccessToken(); | ||
let authenticatedRequest = request.clone(); | ||
authenticatedRequest.headers.set('Authorization', 'Bearer ' + accessToken); | ||
let response = await next(authenticatedRequest); | ||
if (!response.ok && response.status === 401) { | ||
const newToken = await this.refreshToken(); | ||
authenticatedRequest = request.clone(); | ||
authenticatedRequest.headers.set('Authorization', 'Bearer ' + newToken.accessToken); | ||
response = await next(authenticatedRequest); | ||
} | ||
return response; | ||
mw() { | ||
return async (request, next) => { | ||
const accessToken = await this.getAccessToken(); | ||
// Make a clone. We need to clone if we need to retry the request later. | ||
let authenticatedRequest = request.clone(); | ||
authenticatedRequest.headers.set('Authorization', 'Bearer ' + accessToken); | ||
let response = await next(authenticatedRequest); | ||
if (!response.ok && response.status === 401) { | ||
const newToken = await this.refreshToken(); | ||
authenticatedRequest = request.clone(); | ||
authenticatedRequest.headers.set('Authorization', 'Bearer ' + newToken.accessToken); | ||
response = await next(authenticatedRequest); | ||
} | ||
return response; | ||
}; | ||
} | ||
@@ -71,2 +75,4 @@ /** | ||
* * refreshToken - may be null | ||
* | ||
* This function will attempt to automatically refresh if stale. | ||
*/ | ||
@@ -94,2 +100,3 @@ async getToken() { | ||
async refreshToken() { | ||
var _a, _b; | ||
if (this.activeRefresh) { | ||
@@ -100,9 +107,38 @@ // If we are currently already doing this operation, | ||
} | ||
this.activeRefresh = util_1.refreshToken(this.options, this.token); | ||
const oldToken = this.token; | ||
this.activeRefresh = (async () => { | ||
var _a, _b; | ||
let newToken = null; | ||
try { | ||
if (oldToken === null || oldToken === void 0 ? void 0 : oldToken.refreshToken) { | ||
// We had a refresh token, lets see if we can use it! | ||
newToken = await this.options.client.refreshToken(oldToken); | ||
} | ||
} | ||
catch (err) { | ||
console.warn('[oauth2] refresh token not accepted, we\'ll try reauthenticating'); | ||
} | ||
if (!newToken) { | ||
newToken = await this.options.getNewToken(); | ||
} | ||
if (!newToken) { | ||
const err = new Error('Unableto obtain OAuth2 tokens, a full reauth may be needed'); | ||
(_b = (_a = this.options).onError) === null || _b === void 0 ? void 0 : _b.call(_a, err); | ||
throw err; | ||
} | ||
return newToken; | ||
})(); | ||
try { | ||
const token = await this.activeRefresh; | ||
this.token = token; | ||
(_b = (_a = this.options).storeToken) === null || _b === void 0 ? void 0 : _b.call(_a, token); | ||
this.scheduleRefresh(); | ||
return token; | ||
} | ||
catch (err) { | ||
if (this.options.onError) { | ||
this.options.onError(err); | ||
} | ||
throw err; | ||
} | ||
finally { | ||
@@ -139,3 +175,3 @@ // Make sure we clear the current refresh operation. | ||
} | ||
exports.default = OAuth2; | ||
exports.OAuth2Fetch = OAuth2Fetch; | ||
//# sourceMappingURL=fetch-wrapper.js.map |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.OAuth2Error = exports.OAuth2 = exports.fetchMwOAuth2 = exports.default = void 0; | ||
exports.OAuth2Error = exports.OAuth2Fetch = exports.generateCodeVerifier = exports.OAuth2AuthorizationCodeClient = exports.OAuth2Client = void 0; | ||
var client_1 = require("./client"); | ||
Object.defineProperty(exports, "OAuth2Client", { enumerable: true, get: function () { return client_1.OAuth2Client; } }); | ||
var authorization_code_1 = require("./client/authorization-code"); | ||
Object.defineProperty(exports, "OAuth2AuthorizationCodeClient", { enumerable: true, get: function () { return authorization_code_1.OAuth2AuthorizationCodeClient; } }); | ||
Object.defineProperty(exports, "generateCodeVerifier", { enumerable: true, get: function () { return authorization_code_1.generateCodeVerifier; } }); | ||
var fetch_wrapper_1 = require("./fetch-wrapper"); | ||
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(fetch_wrapper_1).default; } }); | ||
Object.defineProperty(exports, "fetchMwOAuth2", { enumerable: true, get: function () { return __importDefault(fetch_wrapper_1).default; } }); | ||
Object.defineProperty(exports, "OAuth2", { enumerable: true, get: function () { return __importDefault(fetch_wrapper_1).default; } }); | ||
Object.defineProperty(exports, "OAuth2Fetch", { enumerable: true, get: function () { return fetch_wrapper_1.OAuth2Fetch; } }); | ||
var error_1 = require("./error"); | ||
Object.defineProperty(exports, "OAuth2Error", { enumerable: true, get: function () { return __importDefault(error_1).default; } }); | ||
Object.defineProperty(exports, "OAuth2Error", { enumerable: true, get: function () { return error_1.OAuth2Error; } }); | ||
//# sourceMappingURL=index.js.map |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.refreshToken = exports.objToQueryString = void 0; | ||
const base64_1 = require("./base64"); | ||
const error_1 = __importDefault(require("./error")); | ||
const error_1 = require("./error"); | ||
/** | ||
@@ -89,3 +86,3 @@ * A simple querystring.stringify alternative, so we don't need to include | ||
usesBasicAuth = true; | ||
const basicAuthStr = base64_1.encode(options.clientId + ':' + options.clientSecret); | ||
const basicAuthStr = (0, base64_1.encode)(options.clientId + ':' + options.clientSecret); | ||
headers.Authorization = 'Basic ' + basicAuthStr; | ||
@@ -92,0 +89,0 @@ } |
{ | ||
"name": "fetch-mw-oauth2", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "Fetch middleware to add OAuth2 support", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
# fetch-mw-oauth2 | ||
_Note that v2 of this package has been renamed to `@badgateway/oauth2-client`. This | ||
package has the same features (and more). v1 will receive some maintenance for the | ||
forseeable future, but uprading is strongly recommended._ | ||
This library adds support to OAuth2 to fetch by wrapping the fetch function. | ||
@@ -4,0 +8,0 @@ It works both for `fetch()` in a browser, as well as [node-fetch][1]. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
150860
48
1933
141
9