fetch-mw-oauth2
Advanced tools
Comparing version 2.0.8 to 2.0.9
@@ -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,(()=>(()=>{"use strict";var e={934:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateQueryString=t.tokenResponseToOAuth2Token=t.OAuth2Client=void 0;const n=r(443),i=r(618);function o(e,t){return new URL(e,t).toString()}function s(e){return e.then((e=>{var t;return{accessToken:e.access_token,expiresAt:e.expires_in?Date.now()+1e3*e.expires_in:null,refreshToken:null!==(t=e.refresh_token)&&void 0!==t?t:null}}))}function a(e){return new URLSearchParams(Object.fromEntries(Object.entries(e).filter((([e,t])=>void 0!==t)))).toString()}t.OAuth2Client=class{constructor(e){this.discoveryDone=!1,this.serverMetadata=null,this.settings=e}async refreshToken(e){if(!e.refreshToken)throw new Error("This token didn't have a refreshToken. It's not possible to refresh this");const t={grant_type:"refresh_token",refresh_token:e.refreshToken};return this.settings.clientSecret||(t.client_id=this.settings.clientId),s(this.request("tokenEndpoint",t))}async clientCredentials(e){var t;const r={grant_type:"client_credentials",scope:null===(t=null==e?void 0:e.scope)||void 0===t?void 0:t.join(" ")};if(!this.settings.clientSecret)throw new Error("A clientSecret must be provied to use client_credentials");return s(this.request("tokenEndpoint",r))}async password(e){var t;const r={grant_type:"password",...e,scope:null===(t=e.scope)||void 0===t?void 0:t.join(" ")};if(!this.settings.clientSecret)throw new Error("A clientSecret must be provied to use client_credentials");return s(this.request("tokenEndpoint",r))}get authorizationCode(){return new i.OAuth2AuthorizationCodeClient(this)}async introspect(e){const t={token:e.accessToken,token_type_hint:"access_token"};return this.request("introspectionEndpoint",t)}async getEndpoint(e){if(void 0!==this.settings[e])return o(this.settings[e],this.settings.server);if("discoveryEndpoint"!==e&&(await this.discover(),void 0!==this.settings[e]))return o(this.settings[e],this.settings.server);if(!this.settings.server)throw new Error(`Could not determine the location of ${e}. Either specify ${e} in the settings, or the "server" endpoint to let the client discover it.`);switch(e){case"authorizationEndpoint":return o("/authorize",this.settings.server);case"tokenEndpoint":return o("/token",this.settings.server);case"discoveryEndpoint":return o("/.well-known/oauth-authorization-server",this.settings.server);case"introspectionEndpoint":return o("/introspect",this.settings.server)}}async discover(){if(this.discoveryDone)return;let e;this.discoveryDone=!0;try{e=await this.getEndpoint("discoveryEndpoint")}catch(e){return void console.warn('[oauth2] OAuth2 discovery endpoint could not be determined. Either specify the "server" or "discoveryEndpoint')}const t=await fetch(e,{headers:{Accept:"application/json"}});if(!t.ok)return;if(!t.headers.has("Content-Type")||t.headers.get("Content-Type").startsWith("application/json"))return void console.warn("[oauth2] OAuth2 discovery endpoint was not a JSON response. Response is ignored");this.serverMetadata=await t.json();const r=[["authorization_endpoint","authorizationEndpoint"],["token_endpoint","tokenEndpoint"],["introspection_endpoint","introspectionEndpoint"]];if(null!==this.serverMetadata)for(const[t,n]of r)this.serverMetadata[t]&&(this.settings[n]=o(this.serverMetadata[t],e))}async request(e,t){const r=await this.getEndpoint(e),i={};if("authorization_code"!==t.grant_type&&this.settings.clientSecret){const e=btoa(this.settings.clientId+":"+this.settings.clientSecret);i.Authorization="Basic "+e}const o=await fetch(r,{method:"POST",body:a(t),headers:i});if(o.ok)return await o.json();let s,c,h;throw o.headers.has("Content-Type")&&o.headers.get("Content-Type").startsWith("application/json")&&(s=await o.json()),(null==s?void 0:s.error)?(c="OAuth2 error "+s.error+".",s.error_description&&(c+=" "+s.error_description),h=s.error):(c="HTTP Error "+o.status+" "+o.statusText,401===o.status&&this.settings.clientSecret&&(c+=". It's likely that the clientId and/or clientSecret was incorrect"),h=null),new n.OAuth2Error(c,h,o.status)}},t.tokenResponseToOAuth2Token=s,t.generateQueryString=a},618:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateCodeVerifier=t.OAuth2AuthorizationCodeClient=void 0;const n=r(934),i=r(443);async function o(e){return["S256",a(await crypto.subtle.digest("SHA-256",s(e)))]}function s(e){const t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=255&e.charCodeAt(r);return t}function a(e){return btoa(String.fromCharCode(...new Uint8Array(e))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}t.OAuth2AuthorizationCodeClient=class{constructor(e){this.client=e}async getAuthorizeUri(e){const[t,r]=await Promise.all([e.codeVerifier?o(e.codeVerifier):void 0,this.client.getEndpoint("authorizationEndpoint")]),i={response_type:"code",client_id:this.client.settings.clientId,redirect_uri:e.redirectUri,code_challenge_method:null==t?void 0:t[0],code_challenge:null==t?void 0:t[1]};return e.state&&(i.state=e.state),r+"?"+(0,n.generateQueryString)(i)}async getTokenFromCodeRedirect(e,t){const{code:r}=await this.validateResponse(e,{state:t.state});return this.getToken({code:r,redirectUri:t.redirectUri,codeVerifier:t.codeVerifier})}async validateResponse(e,t){var r;const n=new URL(e).searchParams;if(n.has("error"))throw new i.OAuth2Error(null!==(r=n.get("error_description"))&&void 0!==r?r:"OAuth2 error",n.get("error"),0);if(!n.has("code"))throw new Error(`The url did not contain a code parameter ${e}`);if(!n.has("state"))throw new Error(`The url did not contain state parameter ${e}`);if(t.state&&t.state!==n.get("state"))throw new Error(`The "state" parameter in the url did not match the expected value of ${t.state}`);return{code:n.get("code")}}async getToken(e){const t={grant_type:"authorization_code",code:e.code,redirect_uri:e.redirectUri,client_id:this.client.settings.clientId,code_verifier:e.codeVerifier};return(0,n.tokenResponseToOAuth2Token)(this.client.request("tokenEndpoint",t))}},t.generateCodeVerifier=function(){const e=new Uint8Array(32);return crypto.getRandomValues(e),a(e)}},443:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2Error=void 0;class r extends Error{constructor(e,t,r){super(e),this.oauth2Code=t,this.httpCode=r}}t.OAuth2Error=r},13:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2Fetch=void 0,t.OAuth2Fetch=class{constructor(e){this.token=null,this.activeRefresh=null,this.refreshTimer=null,this.options=e,e.getStoredToken&&(async()=>{this.token=await e.getStoredToken()})(),this.scheduleRefresh()}async fetch(e,t){const r=new Request(e,t);return this.mw()(r,(e=>fetch(e)))}mw(){return async(e,t)=>{const r=await this.getAccessToken();let n=e.clone();n.headers.set("Authorization","Bearer "+r);let i=await t(n);if(!i.ok&&401===i.status){const r=await this.refreshToken();n=e.clone(),n.headers.set("Authorization","Bearer "+r.accessToken),i=await t(n)}return i}}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(){var e,t;if(this.activeRefresh)return this.activeRefresh;const r=this.token;this.activeRefresh=(async()=>{var e,t;let n=null;try{(null==r?void 0:r.refreshToken)&&(n=await this.options.client.refreshToken(r))}catch(e){console.warn("[oauth2] refresh token not accepted, we'll try reauthenticating")}if(n||(n=await this.options.getNewToken()),!n){const r=new Error("Unableto obtain OAuth2 tokens, a full reauth may be needed");throw null===(t=(e=this.options).onError)||void 0===t||t.call(e,r),r}return n})();try{const r=await this.activeRefresh;return this.token=r,null===(t=(e=this.options).storeToken)||void 0===t||t.call(e,r),this.scheduleRefresh(),r}catch(e){throw this.options.onError&&this.options.onError(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))}}}},t={};function r(n){var i=t[n];if(void 0!==i)return i.exports;var o=t[n]={exports:{}};return e[n](o,o.exports,r),o.exports}var n={};return(()=>{var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.OAuth2Error=e.OAuth2Fetch=e.generateCodeVerifier=e.OAuth2AuthorizationCodeClient=e.OAuth2Client=void 0;var t=r(934);Object.defineProperty(e,"OAuth2Client",{enumerable:!0,get:function(){return t.OAuth2Client}});var i=r(618);Object.defineProperty(e,"OAuth2AuthorizationCodeClient",{enumerable:!0,get:function(){return i.OAuth2AuthorizationCodeClient}}),Object.defineProperty(e,"generateCodeVerifier",{enumerable:!0,get:function(){return i.generateCodeVerifier}});var o=r(13);Object.defineProperty(e,"OAuth2Fetch",{enumerable:!0,get:function(){return o.OAuth2Fetch}});var s=r(443);Object.defineProperty(e,"OAuth2Error",{enumerable:!0,get:function(){return s.OAuth2Error}})})(),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={934:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateQueryString=t.tokenResponseToOAuth2Token=t.OAuth2Client=void 0;const n=r(443),o=r(618);function i(e,t){return new URL(e,t).toString()}function s(e){return e.then((e=>{var t;return{accessToken:e.access_token,expiresAt:e.expires_in?Date.now()+1e3*e.expires_in:null,refreshToken:null!==(t=e.refresh_token)&&void 0!==t?t:null}}))}function a(e){return new URLSearchParams(Object.fromEntries(Object.entries(e).filter((([e,t])=>void 0!==t)))).toString()}t.OAuth2Client=class{constructor(e){this.discoveryDone=!1,this.serverMetadata=null,this.settings=e}async refreshToken(e){if(!e.refreshToken)throw new Error("This token didn't have a refreshToken. It's not possible to refresh this");const t={grant_type:"refresh_token",refresh_token:e.refreshToken};return this.settings.clientSecret||(t.client_id=this.settings.clientId),s(this.request("tokenEndpoint",t))}async clientCredentials(e){var t;const r={grant_type:"client_credentials",scope:null===(t=null==e?void 0:e.scope)||void 0===t?void 0:t.join(" ")};if(!this.settings.clientSecret)throw new Error("A clientSecret must be provied to use client_credentials");return s(this.request("tokenEndpoint",r))}async password(e){var t;const r={grant_type:"password",...e,scope:null===(t=e.scope)||void 0===t?void 0:t.join(" ")};if(!this.settings.clientSecret)throw new Error("A clientSecret must be provied to use client_credentials");return s(this.request("tokenEndpoint",r))}get authorizationCode(){return new o.OAuth2AuthorizationCodeClient(this)}async introspect(e){const t={token:e.accessToken,token_type_hint:"access_token"};return this.request("introspectionEndpoint",t)}async getEndpoint(e){if(void 0!==this.settings[e])return i(this.settings[e],this.settings.server);if("discoveryEndpoint"!==e&&(await this.discover(),void 0!==this.settings[e]))return i(this.settings[e],this.settings.server);if(!this.settings.server)throw new Error(`Could not determine the location of ${e}. Either specify ${e} in the settings, or the "server" endpoint to let the client discover it.`);switch(e){case"authorizationEndpoint":return i("/authorize",this.settings.server);case"tokenEndpoint":return i("/token",this.settings.server);case"discoveryEndpoint":return i("/.well-known/oauth-authorization-server",this.settings.server);case"introspectionEndpoint":return i("/introspect",this.settings.server)}}async discover(){if(this.discoveryDone)return;let e;this.discoveryDone=!0;try{e=await this.getEndpoint("discoveryEndpoint")}catch(e){return void console.warn('[oauth2] OAuth2 discovery endpoint could not be determined. Either specify the "server" or "discoveryEndpoint')}const t=await fetch(e,{headers:{Accept:"application/json"}});if(!t.ok)return;if(!t.headers.has("Content-Type")||t.headers.get("Content-Type").startsWith("application/json"))return void console.warn("[oauth2] OAuth2 discovery endpoint was not a JSON response. Response is ignored");this.serverMetadata=await t.json();const r=[["authorization_endpoint","authorizationEndpoint"],["token_endpoint","tokenEndpoint"],["introspection_endpoint","introspectionEndpoint"]];if(null!==this.serverMetadata)for(const[t,n]of r)this.serverMetadata[t]&&(this.settings[n]=i(this.serverMetadata[t],e))}async request(e,t){const r=await this.getEndpoint(e),o={"Content-Type":"application/x-www-form-urlencoded"};if("authorization_code"!==t.grant_type&&this.settings.clientSecret){const e=btoa(this.settings.clientId+":"+this.settings.clientSecret);o.Authorization="Basic "+e}const i=await fetch(r,{method:"POST",body:a(t),headers:o});if(i.ok)return await i.json();let s,c,h;throw i.headers.has("Content-Type")&&i.headers.get("Content-Type").startsWith("application/json")&&(s=await i.json()),(null==s?void 0:s.error)?(c="OAuth2 error "+s.error+".",s.error_description&&(c+=" "+s.error_description),h=s.error):(c="HTTP Error "+i.status+" "+i.statusText,401===i.status&&this.settings.clientSecret&&(c+=". It's likely that the clientId and/or clientSecret was incorrect"),h=null),new n.OAuth2Error(c,h,i.status)}},t.tokenResponseToOAuth2Token=s,t.generateQueryString=a},618:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateCodeVerifier=t.OAuth2AuthorizationCodeClient=void 0;const n=r(934),o=r(443);async function i(e){return["S256",a(await crypto.subtle.digest("SHA-256",s(e)))]}function s(e){const t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=255&e.charCodeAt(r);return t}function a(e){return btoa(String.fromCharCode(...new Uint8Array(e))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}t.OAuth2AuthorizationCodeClient=class{constructor(e){this.client=e}async getAuthorizeUri(e){const[t,r]=await Promise.all([e.codeVerifier?i(e.codeVerifier):void 0,this.client.getEndpoint("authorizationEndpoint")]),o={response_type:"code",client_id:this.client.settings.clientId,redirect_uri:e.redirectUri,code_challenge_method:null==t?void 0:t[0],code_challenge:null==t?void 0:t[1]};return e.state&&(o.state=e.state),r+"?"+(0,n.generateQueryString)(o)}async getTokenFromCodeRedirect(e,t){const{code:r}=await this.validateResponse(e,{state:t.state});return this.getToken({code:r,redirectUri:t.redirectUri,codeVerifier:t.codeVerifier})}async validateResponse(e,t){var r;const n=new URL(e).searchParams;if(n.has("error"))throw new o.OAuth2Error(null!==(r=n.get("error_description"))&&void 0!==r?r:"OAuth2 error",n.get("error"),0);if(!n.has("code"))throw new Error(`The url did not contain a code parameter ${e}`);if(!n.has("state"))throw new Error(`The url did not contain state parameter ${e}`);if(t.state&&t.state!==n.get("state"))throw new Error(`The "state" parameter in the url did not match the expected value of ${t.state}`);return{code:n.get("code")}}async getToken(e){const t={grant_type:"authorization_code",code:e.code,redirect_uri:e.redirectUri,client_id:this.client.settings.clientId,code_verifier:e.codeVerifier};return(0,n.tokenResponseToOAuth2Token)(this.client.request("tokenEndpoint",t))}},t.generateCodeVerifier=function(){const e=new Uint8Array(32);return crypto.getRandomValues(e),a(e)}},443:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2Error=void 0;class r extends Error{constructor(e,t,r){super(e),this.oauth2Code=t,this.httpCode=r}}t.OAuth2Error=r},13:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2Fetch=void 0,t.OAuth2Fetch=class{constructor(e){this.token=null,this.activeRefresh=null,this.refreshTimer=null,this.options=e,e.getStoredToken&&(async()=>{this.token=await e.getStoredToken()})(),this.scheduleRefresh()}async fetch(e,t){const r=new Request(e,t);return this.mw()(r,(e=>fetch(e)))}mw(){return async(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(){var e,t;if(this.activeRefresh)return this.activeRefresh;const r=this.token;this.activeRefresh=(async()=>{var e,t;let n=null;try{(null==r?void 0:r.refreshToken)&&(n=await this.options.client.refreshToken(r))}catch(e){console.warn("[oauth2] refresh token not accepted, we'll try reauthenticating")}if(n||(n=await this.options.getNewToken()),!n){const r=new Error("Unableto obtain OAuth2 tokens, a full reauth may be needed");throw null===(t=(e=this.options).onError)||void 0===t||t.call(e,r),r}return n})();try{const r=await this.activeRefresh;return this.token=r,null===(t=(e=this.options).storeToken)||void 0===t||t.call(e,r),this.scheduleRefresh(),r}catch(e){throw this.options.onError&&this.options.onError(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))}}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}var n={};return(()=>{var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.OAuth2Error=e.OAuth2Fetch=e.generateCodeVerifier=e.OAuth2AuthorizationCodeClient=e.OAuth2Client=void 0;var t=r(934);Object.defineProperty(e,"OAuth2Client",{enumerable:!0,get:function(){return t.OAuth2Client}});var o=r(618);Object.defineProperty(e,"OAuth2AuthorizationCodeClient",{enumerable:!0,get:function(){return o.OAuth2AuthorizationCodeClient}}),Object.defineProperty(e,"generateCodeVerifier",{enumerable:!0,get:function(){return o.generateCodeVerifier}});var i=r(13);Object.defineProperty(e,"OAuth2Fetch",{enumerable:!0,get:function(){return i.OAuth2Fetch}});var s=r(443);Object.defineProperty(e,"OAuth2Error",{enumerable:!0,get:function(){return s.OAuth2Error}})})(),n})())); | ||
//# sourceMappingURL=fetch-mw-oauth2.min.js.map |
@@ -150,3 +150,5 @@ "use strict"; | ||
const uri = await this.getEndpoint(endpoint); | ||
const headers = {}; | ||
const headers = { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}; | ||
if (body.grant_type !== 'authorization_code' && this.settings.clientSecret) { | ||
@@ -153,0 +155,0 @@ const basicAuthStr = btoa(this.settings.clientId + ':' + this.settings.clientSecret); |
{ | ||
"name": "fetch-mw-oauth2", | ||
"version": "2.0.8", | ||
"version": "2.0.9", | ||
"description": "Fetch middleware to add OAuth2 support", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -264,3 +264,5 @@ import { OAuth2Token } from './token'; | ||
const headers: Record<string, string> = {}; | ||
const headers: Record<string, string> = { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}; | ||
@@ -267,0 +269,0 @@ if (body.grant_type !== 'authorization_code' && this.settings.clientSecret) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
146007
2258