@badgateway/oauth2-client
Advanced tools
Comparing version 2.4.0 to 2.4.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.OAuth2Client=t():e.OAuth2Client=t()}(self,(()=>(()=>{var e={985:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2Client=void 0,t.generateQueryString=i;const n=r(854),o=r(129);function s(e,t){return new URL(e,t).toString()}function i(e){const t=new URLSearchParams;for(const[r,n]of Object.entries(e))if(Array.isArray(n))for(const e of n)t.append(r,e);else void 0!==n&&t.set(r,n.toString());return t.toString()}t.OAuth2Client=class{constructor(e){this.discoveryDone=!1,this.serverMetadata=null,(null==e?void 0:e.fetch)||(e.fetch=fetch.bind(globalThis)),this.settings=e}async refreshToken(e,t){if(!e.refreshToken)throw new Error("This token didn't have a refreshToken. It's not possible to refresh this");const r={grant_type:"refresh_token",refresh_token:e.refreshToken};return this.settings.clientSecret||(r.client_id=this.settings.clientId),(null==t?void 0:t.scope)&&(r.scope=t.scope.join(" ")),(null==t?void 0:t.resource)&&(r.resource=t.resource),this.tokenResponseToOAuth2Token(this.request("tokenEndpoint",r))}async clientCredentials(e){var t;const r=["client_id","client_secret","grant_type","scope"];if((null==e?void 0:e.extraParams)&&Object.keys(e.extraParams).filter((e=>r.includes(e))).length>0)throw new Error(`The following extraParams are disallowed: '${r.join("', '")}'`);const n={grant_type:"client_credentials",scope:null===(t=null==e?void 0:e.scope)||void 0===t?void 0:t.join(" "),resource:null==e?void 0:e.resource,...null==e?void 0:e.extraParams};if(!this.settings.clientSecret)throw new Error("A clientSecret must be provided to use client_credentials");return this.tokenResponseToOAuth2Token(this.request("tokenEndpoint",n))}async password(e){var t;const r={grant_type:"password",...e,scope:null===(t=e.scope)||void 0===t?void 0:t.join(" ")};return this.tokenResponseToOAuth2Token(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 revoke(e,t="access_token"){let r=e.accessToken;"refresh_token"===t&&(r=e.refreshToken);const n={token:r,token_type_hint:t};return this.request("revocationEndpoint",n)}async getEndpoint(e){if(void 0!==this.settings[e])return s(this.settings[e],this.settings.server);if("discoveryEndpoint"!==e&&(await this.discover(),void 0!==this.settings[e]))return s(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 s("/authorize",this.settings.server);case"tokenEndpoint":return s("/token",this.settings.server);case"discoveryEndpoint":return s("/.well-known/oauth-authorization-server",this.settings.server);case"introspectionEndpoint":return s("/introspect",this.settings.server);case"revocationEndpoint":return s("/revoke",this.settings.server)}}async discover(){var e;if(this.discoveryDone)return;let t;this.discoveryDone=!0;try{t=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 r=await this.settings.fetch(t,{headers:{Accept:"application/json"}});if(!r.ok)return;if(!(null===(e=r.headers.get("Content-Type"))||void 0===e?void 0:e.startsWith("application/json")))return void console.warn("[oauth2] OAuth2 discovery endpoint was not a JSON response. Response is ignored");this.serverMetadata=await r.json();const n=[["authorization_endpoint","authorizationEndpoint"],["token_endpoint","tokenEndpoint"],["introspection_endpoint","introspectionEndpoint"],["revocation_endpoint","revocationEndpoint"]];if(null!==this.serverMetadata){for(const[e,r]of n)this.serverMetadata[e]&&(this.settings[r]=s(this.serverMetadata[e],t));this.serverMetadata.token_endpoint_auth_methods_supported&&!this.settings.authenticationMethod&&(this.settings.authenticationMethod=this.serverMetadata.token_endpoint_auth_methods_supported[0])}}async request(e,t){const r=await this.getEndpoint(e),o={"Content-Type":"application/x-www-form-urlencoded"};let s=this.settings.authenticationMethod;switch(this.settings.clientSecret||(s="client_secret_post"),s||(s="client_secret_basic"),s){case"client_secret_basic":o.Authorization="Basic "+btoa(this.settings.clientId+":"+this.settings.clientSecret);break;case"client_secret_post":t.client_id=this.settings.clientId,this.settings.clientSecret&&(t.client_secret=this.settings.clientSecret);break;default:throw new Error("Authentication method not yet supported:"+s+". Open a feature request if you want this!")}const a=await this.settings.fetch(r,{method:"POST",body:i(t),headers:o});let c,h,u;if(204!==a.status&&a.headers.has("Content-Type")&&a.headers.get("Content-Type").match(/^application\/(.*\+)?json/)&&(c=await a.json()),a.ok)return c;throw(null==c?void 0:c.error)?(h="OAuth2 error "+c.error+".",c.error_description&&(h+=" "+c.error_description),u=c.error):(h="HTTP Error "+a.status+" "+a.statusText,401===a.status&&this.settings.clientSecret&&(h+=". It's likely that the clientId and/or clientSecret was incorrect"),u=null),new n.OAuth2HttpError(h,u,a,c)}tokenResponseToOAuth2Token(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}}))}}},129:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2AuthorizationCodeClient=void 0,t.generateCodeVerifier=async function(){const e=s();if(e){const t=new Uint8Array(32);return e.getRandomValues(t),a(t)}{const e=r(483);return new Promise(((t,r)=>{e.randomBytes(32,((e,n)=>{e&&r(e),t(n.toString("base64url"))}))}))}},t.getCodeChallenge=o;const n=r(854);async function o(e){const t=s();if(null==t?void 0:t.subtle)return["S256",a(await t.subtle.digest("SHA-256",i(e)))];{const t=r(483).createHash("sha256");return t.update(i(e)),["S256",t.digest("base64url")]}}function s(){if("undefined"!=typeof window&&window.crypto)return window.crypto;if("undefined"!=typeof self&&self.crypto)return self.crypto;const e=r(483);return e.webcrypto?e.webcrypto:null}function i(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")]),n=new URLSearchParams({client_id:this.client.settings.clientId,response_type:"code",redirect_uri:e.redirectUri});if(t&&(n.set("code_challenge_method",t[0]),n.set("code_challenge",t[1])),e.state&&n.set("state",e.state),e.scope&&n.set("scope",e.scope.join(" ")),e.resource)for(const t of[].concat(e.resource))n.append("resource",t);if(e.responseMode&&"query"!==e.responseMode&&n.append("response_mode",e.responseMode),e.extraParams)for(const[t,r]of Object.entries(e.extraParams)){if(n.has(t))throw new Error(`Property in extraParams would overwrite standard property: ${t}`);n.set(t,r)}return r+"?"+n.toString()}async getTokenFromCodeRedirect(e,t){const{code:r}=this.validateResponse(e,{state:t.state});return this.getToken({code:r,redirectUri:t.redirectUri,codeVerifier:t.codeVerifier})}validateResponse(e,t){var r;let o=(e=new URL(e)).searchParams;if(!o.has("code")&&!o.has("error")&&e.hash.length>0&&(o=new URLSearchParams(e.hash.slice(1))),o.has("error"))throw new n.OAuth2Error(null!==(r=o.get("error_description"))&&void 0!==r?r:"OAuth2 error",o.get("error"));if(!o.has("code"))throw new Error(`The url did not contain a code parameter ${e}`);if(t.state&&t.state!==o.get("state"))throw new Error(`The "state" parameter in the url did not match the expected value of ${t.state}`);return{code:o.get("code"),scope:o.has("scope")?o.get("scope").split(" "):void 0}}async getToken(e){const t={grant_type:"authorization_code",code:e.code,redirect_uri:e.redirectUri,code_verifier:e.codeVerifier,resource:e.resource};return this.client.tokenResponseToOAuth2Token(this.client.request("tokenEndpoint",t))}}},854:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2HttpError=t.OAuth2Error=void 0;class r extends Error{constructor(e,t){super(e),this.oauth2Code=t}}t.OAuth2Error=r,t.OAuth2HttpError=class extends r{constructor(e,t,r,n){super(e,t),this.httpCode=r.status,this.response=r,this.parsedBody=n}}},238:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2Fetch=void 0,t.OAuth2Fetch=class{constructor(e){this.token=null,this.activeGetStoredToken=null,this.activeRefresh=null,this.refreshTimer=null,void 0===(null==e?void 0:e.scheduleRefresh)&&(e.scheduleRefresh=!0),this.options=e,e.getStoredToken&&(this.activeGetStoredToken=(async()=>{this.token=await e.getStoredToken(),this.activeGetStoredToken=null})()),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.activeGetStoredToken,(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("Unable to 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(){var e;if(!this.options.scheduleRefresh)return;if(this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null),!(null===(e=this.token)||void 0===e?void 0:e.expiresAt)||!this.token.refreshToken)return;const t=this.token.expiresAt-Date.now();t<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)}}),t-6e4))}}},483:()=>{}},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(()=>{"use strict";var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.OAuth2HttpError=e.OAuth2Error=e.OAuth2Fetch=e.generateCodeVerifier=e.OAuth2AuthorizationCodeClient=e.OAuth2Client=void 0;var t=r(985);Object.defineProperty(e,"OAuth2Client",{enumerable:!0,get:function(){return t.OAuth2Client}});var o=r(129);Object.defineProperty(e,"OAuth2AuthorizationCodeClient",{enumerable:!0,get:function(){return o.OAuth2AuthorizationCodeClient}}),Object.defineProperty(e,"generateCodeVerifier",{enumerable:!0,get:function(){return o.generateCodeVerifier}});var s=r(238);Object.defineProperty(e,"OAuth2Fetch",{enumerable:!0,get:function(){return s.OAuth2Fetch}});var i=r(854);Object.defineProperty(e,"OAuth2Error",{enumerable:!0,get:function(){return i.OAuth2Error}}),Object.defineProperty(e,"OAuth2HttpError",{enumerable:!0,get:function(){return i.OAuth2HttpError}})})(),n})())); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.OAuth2Client=t():e.OAuth2Client=t()}(self,(()=>(()=>{var e={985:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2Client=void 0,t.generateQueryString=i;const n=r(854),o=r(129);function s(e,t){return new URL(e,t).toString()}function i(e){const t=new URLSearchParams;for(const[r,n]of Object.entries(e))if(Array.isArray(n))for(const e of n)t.append(r,e);else void 0!==n&&t.set(r,n.toString());return t.toString()}t.OAuth2Client=class{constructor(e){this.discoveryDone=!1,this.serverMetadata=null,(null==e?void 0:e.fetch)||(e.fetch=fetch.bind(globalThis)),this.settings=e}async refreshToken(e,t){if(!e.refreshToken)throw new Error("This token didn't have a refreshToken. It's not possible to refresh this");const r={grant_type:"refresh_token",refresh_token:e.refreshToken};return this.settings.clientSecret||(r.client_id=this.settings.clientId),(null==t?void 0:t.scope)&&(r.scope=t.scope.join(" ")),(null==t?void 0:t.resource)&&(r.resource=t.resource),this.tokenResponseToOAuth2Token(this.request("tokenEndpoint",r))}async clientCredentials(e){var t;const r=["client_id","client_secret","grant_type","scope"];if((null==e?void 0:e.extraParams)&&Object.keys(e.extraParams).filter((e=>r.includes(e))).length>0)throw new Error(`The following extraParams are disallowed: '${r.join("', '")}'`);const n={grant_type:"client_credentials",scope:null===(t=null==e?void 0:e.scope)||void 0===t?void 0:t.join(" "),resource:null==e?void 0:e.resource,...null==e?void 0:e.extraParams};if(!this.settings.clientSecret)throw new Error("A clientSecret must be provided to use client_credentials");return this.tokenResponseToOAuth2Token(this.request("tokenEndpoint",n))}async password(e){var t;const r={grant_type:"password",...e,scope:null===(t=e.scope)||void 0===t?void 0:t.join(" ")};return this.tokenResponseToOAuth2Token(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 revoke(e,t="access_token"){let r=e.accessToken;"refresh_token"===t&&(r=e.refreshToken);const n={token:r,token_type_hint:t};return this.request("revocationEndpoint",n)}async getEndpoint(e){if(void 0!==this.settings[e])return s(this.settings[e],this.settings.server);if("discoveryEndpoint"!==e&&(await this.discover(),void 0!==this.settings[e]))return s(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 s("/authorize",this.settings.server);case"tokenEndpoint":return s("/token",this.settings.server);case"discoveryEndpoint":return s("/.well-known/oauth-authorization-server",this.settings.server);case"introspectionEndpoint":return s("/introspect",this.settings.server);case"revocationEndpoint":return s("/revoke",this.settings.server)}}async discover(){var e;if(this.discoveryDone)return;let t;this.discoveryDone=!0;try{t=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 r=await this.settings.fetch(t,{headers:{Accept:"application/json"}});if(!r.ok)return;if(!(null===(e=r.headers.get("Content-Type"))||void 0===e?void 0:e.startsWith("application/json")))return void console.warn("[oauth2] OAuth2 discovery endpoint was not a JSON response. Response is ignored");this.serverMetadata=await r.json();const n=[["authorization_endpoint","authorizationEndpoint"],["token_endpoint","tokenEndpoint"],["introspection_endpoint","introspectionEndpoint"],["revocation_endpoint","revocationEndpoint"]];if(null!==this.serverMetadata){for(const[e,r]of n)this.serverMetadata[e]&&(this.settings[r]=s(this.serverMetadata[e],t));this.serverMetadata.token_endpoint_auth_methods_supported&&!this.settings.authenticationMethod&&(this.settings.authenticationMethod=this.serverMetadata.token_endpoint_auth_methods_supported[0])}}async request(e,t){const r=await this.getEndpoint(e),o={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"};let s=this.settings.authenticationMethod;switch(this.settings.clientSecret||(s="client_secret_post"),s||(s="client_secret_basic"),s){case"client_secret_basic":o.Authorization="Basic "+btoa(this.settings.clientId+":"+this.settings.clientSecret);break;case"client_secret_post":t.client_id=this.settings.clientId,this.settings.clientSecret&&(t.client_secret=this.settings.clientSecret);break;default:throw new Error("Authentication method not yet supported:"+s+". Open a feature request if you want this!")}const a=await this.settings.fetch(r,{method:"POST",body:i(t),headers:o});let c,h,u;if(204!==a.status&&a.headers.has("Content-Type")&&a.headers.get("Content-Type").match(/^application\/(.*\+)?json/)&&(c=await a.json()),a.ok)return c;throw(null==c?void 0:c.error)?(h="OAuth2 error "+c.error+".",c.error_description&&(h+=" "+c.error_description),u=c.error):(h="HTTP Error "+a.status+" "+a.statusText,401===a.status&&this.settings.clientSecret&&(h+=". It's likely that the clientId and/or clientSecret was incorrect"),u=null),new n.OAuth2HttpError(h,u,a,c)}async tokenResponseToOAuth2Token(e){var t;const r=await e;if(!(null==r?void 0:r.access_token))throw console.warn("Invalid OAuth2 Token Response: ",r),new TypeError("We received an invalid token response from an OAuth2 server.");return{accessToken:r.access_token,expiresAt:r.expires_in?Date.now()+1e3*r.expires_in:null,refreshToken:null!==(t=r.refresh_token)&&void 0!==t?t:null}}}},129:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2AuthorizationCodeClient=void 0,t.generateCodeVerifier=async function(){const e=s();if(e){const t=new Uint8Array(32);return e.getRandomValues(t),a(t)}{const e=r(483);return new Promise(((t,r)=>{e.randomBytes(32,((e,n)=>{e&&r(e),t(n.toString("base64url"))}))}))}},t.getCodeChallenge=o;const n=r(854);async function o(e){const t=s();if(null==t?void 0:t.subtle)return["S256",a(await t.subtle.digest("SHA-256",i(e)))];{const t=r(483).createHash("sha256");return t.update(i(e)),["S256",t.digest("base64url")]}}function s(){if("undefined"!=typeof window&&window.crypto)return window.crypto;if("undefined"!=typeof self&&self.crypto)return self.crypto;const e=r(483);return e.webcrypto?e.webcrypto:null}function i(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")]),n=new URLSearchParams({client_id:this.client.settings.clientId,response_type:"code",redirect_uri:e.redirectUri});if(t&&(n.set("code_challenge_method",t[0]),n.set("code_challenge",t[1])),e.state&&n.set("state",e.state),e.scope&&n.set("scope",e.scope.join(" ")),e.resource)for(const t of[].concat(e.resource))n.append("resource",t);if(e.responseMode&&"query"!==e.responseMode&&n.append("response_mode",e.responseMode),e.extraParams)for(const[t,r]of Object.entries(e.extraParams)){if(n.has(t))throw new Error(`Property in extraParams would overwrite standard property: ${t}`);n.set(t,r)}return r+"?"+n.toString()}async getTokenFromCodeRedirect(e,t){const{code:r}=this.validateResponse(e,{state:t.state});return this.getToken({code:r,redirectUri:t.redirectUri,codeVerifier:t.codeVerifier})}validateResponse(e,t){var r;let o=(e=new URL(e)).searchParams;if(!o.has("code")&&!o.has("error")&&e.hash.length>0&&(o=new URLSearchParams(e.hash.slice(1))),o.has("error"))throw new n.OAuth2Error(null!==(r=o.get("error_description"))&&void 0!==r?r:"OAuth2 error",o.get("error"));if(!o.has("code"))throw new Error(`The url did not contain a code parameter ${e}`);if(t.state&&t.state!==o.get("state"))throw new Error(`The "state" parameter in the url did not match the expected value of ${t.state}`);return{code:o.get("code"),scope:o.has("scope")?o.get("scope").split(" "):void 0}}async getToken(e){const t={grant_type:"authorization_code",code:e.code,redirect_uri:e.redirectUri,code_verifier:e.codeVerifier,resource:e.resource};return this.client.tokenResponseToOAuth2Token(this.client.request("tokenEndpoint",t))}}},854:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2HttpError=t.OAuth2Error=void 0;class r extends Error{constructor(e,t){super(e),this.oauth2Code=t}}t.OAuth2Error=r,t.OAuth2HttpError=class extends r{constructor(e,t,r,n){super(e,t),this.httpCode=r.status,this.response=r,this.parsedBody=n}}},238:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OAuth2Fetch=void 0,t.OAuth2Fetch=class{constructor(e){this.token=null,this.activeGetStoredToken=null,this.activeRefresh=null,this.refreshTimer=null,void 0===(null==e?void 0:e.scheduleRefresh)&&(e.scheduleRefresh=!0),this.options=e,e.getStoredToken&&(this.activeGetStoredToken=(async()=>{this.token=await e.getStoredToken(),this.activeGetStoredToken=null})()),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.activeGetStoredToken,(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("Unable to 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(){var e;if(!this.options.scheduleRefresh)return;if(this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null),!(null===(e=this.token)||void 0===e?void 0:e.expiresAt)||!this.token.refreshToken)return;const t=this.token.expiresAt-Date.now();t<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)}}),t-6e4))}}},483:()=>{}},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(()=>{"use strict";var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.OAuth2HttpError=e.OAuth2Error=e.OAuth2Fetch=e.generateCodeVerifier=e.OAuth2AuthorizationCodeClient=e.OAuth2Client=void 0;var t=r(985);Object.defineProperty(e,"OAuth2Client",{enumerable:!0,get:function(){return t.OAuth2Client}});var o=r(129);Object.defineProperty(e,"OAuth2AuthorizationCodeClient",{enumerable:!0,get:function(){return o.OAuth2AuthorizationCodeClient}}),Object.defineProperty(e,"generateCodeVerifier",{enumerable:!0,get:function(){return o.generateCodeVerifier}});var s=r(238);Object.defineProperty(e,"OAuth2Fetch",{enumerable:!0,get:function(){return s.OAuth2Fetch}});var i=r(854);Object.defineProperty(e,"OAuth2Error",{enumerable:!0,get:function(){return i.OAuth2Error}}),Object.defineProperty(e,"OAuth2HttpError",{enumerable:!0,get:function(){return i.OAuth2HttpError}})})(),n})())); | ||
//# sourceMappingURL=oauth2-client.min.js.map |
@@ -187,2 +187,5 @@ "use strict"; | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
// Although it shouldn't be needed, Github OAUth2 will return JSON | ||
// unless this is set. | ||
'Accept': 'application/json', | ||
}; | ||
@@ -250,11 +253,14 @@ let authMethod = this.settings.authenticationMethod; | ||
*/ | ||
tokenResponseToOAuth2Token(resp) { | ||
return resp.then(body => { | ||
var _a; | ||
return ({ | ||
accessToken: body.access_token, | ||
expiresAt: body.expires_in ? Date.now() + (body.expires_in * 1000) : null, | ||
refreshToken: (_a = body.refresh_token) !== null && _a !== void 0 ? _a : null, | ||
}); | ||
}); | ||
async tokenResponseToOAuth2Token(resp) { | ||
var _a; | ||
const body = await resp; | ||
if (!(body === null || body === void 0 ? void 0 : body.access_token)) { | ||
console.warn('Invalid OAuth2 Token Response: ', body); | ||
throw new TypeError('We received an invalid token response from an OAuth2 server.'); | ||
} | ||
return { | ||
accessToken: body.access_token, | ||
expiresAt: body.expires_in ? Date.now() + (body.expires_in * 1000) : null, | ||
refreshToken: (_a = body.refresh_token) !== null && _a !== void 0 ? _a : null, | ||
}; | ||
} | ||
@@ -261,0 +267,0 @@ } |
@@ -63,3 +63,3 @@ /** | ||
token_type: string; | ||
expires_in: number; | ||
expires_in?: number; | ||
refresh_token?: string; | ||
@@ -66,0 +66,0 @@ scope?: string; |
{ | ||
"name": "@badgateway/oauth2-client", | ||
"version": "2.4.0", | ||
"version": "2.4.1", | ||
"description": "OAuth2 client for browsers and Node.js. Tiny footprint, PKCE support", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -6,3 +6,3 @@ # OAuth2 client for Node and browsers | ||
This OAuth2 client is only **3.6KB** gzipped, it has **0** dependencies and | ||
This OAuth2 client is only **3.9KB** gzipped, it has **0** dependencies and | ||
relies on modern APIs like `fetch()` and [Web Crypto][4] which are built-in | ||
@@ -14,3 +14,3 @@ since Node 18 (but it works with Polyfills on Node 14 and 16). | ||
* 12KB minified (3.8KB gzipped). | ||
* 12KB minified (3.9KB gzipped). | ||
* No dependencies. | ||
@@ -17,0 +17,0 @@ * `authorization_code` grant with optional [PKCE][1] support. |
@@ -378,2 +378,5 @@ import { OAuth2Token } from './token'; | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
// Although it shouldn't be needed, Github OAUth2 will return JSON | ||
// unless this is set. | ||
'Accept': 'application/json', | ||
}; | ||
@@ -449,9 +452,16 @@ | ||
*/ | ||
tokenResponseToOAuth2Token(resp: Promise<TokenResponse>): Promise<OAuth2Token> { | ||
async tokenResponseToOAuth2Token(resp: Promise<TokenResponse>): Promise<OAuth2Token> { | ||
return resp.then(body => ({ | ||
const body = await resp; | ||
if (!body?.access_token) { | ||
console.warn('Invalid OAuth2 Token Response: ', body); | ||
throw new TypeError('We received an invalid token response from an OAuth2 server.'); | ||
} | ||
return { | ||
accessToken: body.access_token, | ||
expiresAt: body.expires_in ? Date.now() + (body.expires_in * 1000) : null, | ||
refreshToken: body.refresh_token ?? null, | ||
})); | ||
}; | ||
@@ -458,0 +468,0 @@ } |
@@ -73,3 +73,3 @@ /** | ||
token_type: string; | ||
expires_in: number; | ||
expires_in?: number; | ||
refresh_token?: string; | ||
@@ -76,0 +76,0 @@ scope?: string; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
179592
2606