@auth0/auth0-spa-js 2.17.1 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"auth0-spa-js.worker.development.js","sources":["../src/errors.ts","../src/utils.ts","../src/worker/token.worker.ts"],"sourcesContent":["/**\n * MFA requirements from an mfa_required error response\n */\nexport interface MfaRequirements {\n /** Required enrollment types */\n enroll?: Array<{ type: string }>;\n /** Required challenge types */\n challenge?: Array<{ type: string }>;\n}\n\n/**\n * Thrown when network requests to the Auth server fail.\n */\nexport class GenericError extends Error {\n constructor(public error: string, public error_description: string) {\n super(error_description);\n Object.setPrototypeOf(this, GenericError.prototype);\n }\n\n static fromPayload({\n error,\n error_description\n }: {\n error: string;\n error_description: string;\n }) {\n return new GenericError(error, error_description);\n }\n}\n\n/**\n * Thrown when handling the redirect callback fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class AuthenticationError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Thrown when handling the redirect callback for the connect flow fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class ConnectError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public connection: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, ConnectError.prototype);\n }\n}\n\n/**\n * Thrown when silent auth times out (usually due to a configuration issue) or\n * when network requests to the Auth server timeout.\n */\nexport class TimeoutError extends GenericError {\n constructor() {\n super('timeout', 'Timeout');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\n/**\n * Error thrown when the login popup times out (if the user does not complete auth)\n */\nexport class PopupTimeoutError extends TimeoutError {\n constructor(public popup: Window) {\n super();\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupTimeoutError.prototype);\n }\n}\n\nexport class PopupCancelledError extends GenericError {\n constructor(public popup: Window) {\n super('cancelled', 'Popup closed');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupCancelledError.prototype);\n }\n}\n\nexport class PopupOpenError extends GenericError {\n constructor() {\n super('popup_open', 'Unable to open a popup for loginWithPopup - window.open returned `null`');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupOpenError.prototype);\n }\n}\n\n/**\n * Error thrown when the token exchange results in a `mfa_required` error\n */\nexport class MfaRequiredError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public mfa_token: string,\n public mfa_requirements: MfaRequirements\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, MfaRequiredError.prototype);\n }\n}\n\n/**\n * Error thrown when there is no refresh token to use\n */\nexport class MissingRefreshTokenError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_refresh_token',\n `Missing Refresh Token (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingRefreshTokenError.prototype);\n }\n}\n\n/**\n * Error thrown when there are missing scopes after refreshing a token\n */\nexport class MissingScopesError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_scopes',\n `Missing requested scopes after refresh (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', missing scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingScopesError.prototype);\n }\n}\n\n/**\n * Error thrown when the wrong DPoP nonce is used and a potential subsequent retry wasn't able to fix it.\n */\nexport class UseDpopNonceError extends GenericError {\n constructor(public newDpopNonce: string | undefined) {\n super('use_dpop_nonce', 'Server rejected DPoP proof: wrong nonce');\n\n Object.setPrototypeOf(this, UseDpopNonceError.prototype);\n }\n}\n\n/**\n * Returns an empty string when value is falsy, or when it's value is included in the exclude argument.\n * @param value The value to check\n * @param exclude An array of values that should result in an empty string.\n * @returns The value, or an empty string when falsy or included in the exclude argument.\n */\nfunction valueOrEmptyString(value: string, exclude: string[] = []) {\n return value && !exclude.includes(value) ? value : '';\n}\n","import { AuthenticationResult, PopupConfigOptions } from './global';\n\nimport {\n DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS,\n CLEANUP_IFRAME_TIMEOUT_IN_SECONDS\n} from './constants';\n\nimport {\n PopupTimeoutError,\n TimeoutError,\n GenericError,\n PopupCancelledError\n} from './errors';\n\nexport const parseAuthenticationResult = (\n queryString: string\n): AuthenticationResult => {\n if (queryString.indexOf('#') > -1) {\n queryString = queryString.substring(0, queryString.indexOf('#'));\n }\n\n const searchParams = new URLSearchParams(queryString);\n\n return {\n state: searchParams.get('state')!,\n code: searchParams.get('code') || undefined,\n connect_code: searchParams.get('connect_code') || undefined,\n error: searchParams.get('error') || undefined,\n error_description: searchParams.get('error_description') || undefined\n };\n};\n\nexport const runIframe = (\n authorizeUrl: string,\n eventOrigin: string,\n timeoutInSeconds: number = DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS\n) => {\n return new Promise<AuthenticationResult>((res, rej) => {\n const iframe = window.document.createElement('iframe');\n\n iframe.setAttribute('width', '0');\n iframe.setAttribute('height', '0');\n iframe.style.display = 'none';\n\n const removeIframe = () => {\n if (window.document.body.contains(iframe)) {\n window.document.body.removeChild(iframe);\n window.removeEventListener('message', iframeEventHandler, false);\n }\n };\n\n let iframeEventHandler: (e: MessageEvent) => void;\n\n const timeoutSetTimeoutId = setTimeout(() => {\n rej(new TimeoutError());\n removeIframe();\n }, timeoutInSeconds * 1000);\n\n iframeEventHandler = function (e: MessageEvent) {\n if (e.origin != eventOrigin) return;\n if (!e.data || e.data.type !== 'authorization_response') return;\n\n const eventSource = e.source;\n\n if (eventSource) {\n (eventSource as any).close();\n }\n\n e.data.response.error\n ? rej(GenericError.fromPayload(e.data.response))\n : res(e.data.response);\n\n clearTimeout(timeoutSetTimeoutId);\n window.removeEventListener('message', iframeEventHandler, false);\n\n // Delay the removal of the iframe to prevent hanging loading status\n // in Chrome: https://github.com/auth0/auth0-spa-js/issues/240\n setTimeout(removeIframe, CLEANUP_IFRAME_TIMEOUT_IN_SECONDS * 1000);\n };\n\n window.addEventListener('message', iframeEventHandler, false);\n window.document.body.appendChild(iframe);\n iframe.setAttribute('src', authorizeUrl);\n });\n};\n\nexport const openPopup = (url: string) => {\n const width = 400;\n const height = 600;\n const left = window.screenX + (window.innerWidth - width) / 2;\n const top = window.screenY + (window.innerHeight - height) / 2;\n\n return window.open(\n url,\n 'auth0:authorize:popup',\n `left=${left},top=${top},width=${width},height=${height},resizable,scrollbars=yes,status=1`\n );\n};\n\nexport const runPopup = (config: PopupConfigOptions) => {\n return new Promise<AuthenticationResult>((resolve, reject) => {\n let popupEventListener: (e: MessageEvent) => void;\n\n // Check each second if the popup is closed triggering a PopupCancelledError\n const popupTimer = setInterval(() => {\n if (config.popup && config.popup.closed) {\n clearInterval(popupTimer);\n clearTimeout(timeoutId);\n window.removeEventListener('message', popupEventListener, false);\n reject(new PopupCancelledError(config.popup));\n }\n }, 1000);\n\n const timeoutId = setTimeout(() => {\n clearInterval(popupTimer);\n reject(new PopupTimeoutError(config.popup));\n window.removeEventListener('message', popupEventListener, false);\n }, (config.timeoutInSeconds || DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS) * 1000);\n\n popupEventListener = function (e: MessageEvent) {\n if (!e.data || e.data.type !== 'authorization_response') {\n return;\n }\n\n clearTimeout(timeoutId);\n clearInterval(popupTimer);\n window.removeEventListener('message', popupEventListener, false);\n\n // Close popup automatically unless closePopup is explicitly set to false\n if (config.closePopup !== false) {\n config.popup.close();\n }\n\n if (e.data.response.error) {\n return reject(GenericError.fromPayload(e.data.response));\n }\n\n resolve(e.data.response);\n };\n\n window.addEventListener('message', popupEventListener);\n });\n};\n\nexport const getCrypto = () => {\n return window.crypto;\n};\n\nexport const createRandomString = () => {\n const charset =\n '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.';\n let random = '';\n const randomValues = Array.from(\n getCrypto().getRandomValues(new Uint8Array(43))\n );\n randomValues.forEach(v => (random += charset[v % charset.length]));\n return random;\n};\n\nexport const encode = (value: string) => btoa(value);\nexport const decode = (value: string) => atob(value);\n\nconst stripUndefined = (params: any) => {\n return Object.keys(params)\n .filter(k => typeof params[k] !== 'undefined')\n .reduce((acc, key) => ({ ...acc, [key]: params[key] }), {});\n};\n\nconst ALLOWED_AUTH0CLIENT_PROPERTIES = [\n {\n key: 'name',\n type: ['string']\n },\n {\n key: 'version',\n type: ['string', 'number']\n },\n {\n key: 'env',\n type: ['object']\n }\n];\n\n/**\n * Strips any property that is not present in ALLOWED_AUTH0CLIENT_PROPERTIES\n * @param auth0Client - The full auth0Client object\n * @param excludeEnv - If true, excludes the 'env' property from the result\n * @returns The stripped auth0Client object\n */\nexport const stripAuth0Client = (auth0Client: any, excludeEnv = false) => {\n return Object.keys(auth0Client).reduce((acc: any, key: string) => {\n // Exclude 'env' if requested (for /authorize query params to prevent truncation)\n if (excludeEnv && key === 'env') {\n return acc;\n }\n\n const allowedProperty = ALLOWED_AUTH0CLIENT_PROPERTIES.find(\n p => p.key === key\n );\n if (\n allowedProperty &&\n allowedProperty.type.includes(typeof auth0Client[key])\n ) {\n acc[key] = auth0Client[key];\n }\n\n return acc;\n }, {});\n};\n\nexport const createQueryParams = ({ clientId: client_id, ...params }: any) => {\n return new URLSearchParams(\n stripUndefined({ client_id, ...params })\n ).toString();\n};\n\nexport const sha256 = async (s: string) => {\n const digestOp: any = getCrypto().subtle.digest(\n { name: 'SHA-256' },\n new TextEncoder().encode(s)\n );\n\n return await digestOp;\n};\n\nconst urlEncodeB64 = (input: string) => {\n const b64Chars: { [index: string]: string } = { '+': '-', '/': '_', '=': '' };\n return input.replace(/[+/=]/g, (m: string) => b64Chars[m]);\n};\n\n// https://stackoverflow.com/questions/30106476/\nconst decodeB64 = (input: string) =>\n decodeURIComponent(\n atob(input)\n .split('')\n .map(c => {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join('')\n );\n\nexport const urlDecodeB64 = (input: string) =>\n decodeB64(input.replace(/_/g, '/').replace(/-/g, '+'));\n\nexport const bufferToBase64UrlEncoded = (input: number[] | Uint8Array) => {\n const ie11SafeInput = new Uint8Array(input);\n return urlEncodeB64(\n window.btoa(String.fromCharCode(...Array.from(ie11SafeInput)))\n );\n};\n\nexport const validateCrypto = () => {\n if (!getCrypto()) {\n throw new Error(\n 'For security reasons, `window.crypto` is required to run `auth0-spa-js`.'\n );\n }\n if (typeof getCrypto().subtle === 'undefined') {\n throw new Error(`\n auth0-spa-js must run on a secure origin. See https://github.com/auth0/auth0-spa-js/blob/main/FAQ.md#why-do-i-get-auth0-spa-js-must-run-on-a-secure-origin for more information.\n `);\n }\n};\n\n/**\n * @ignore\n */\nexport const getDomain = (domainUrl: string) => {\n if (!/^https?:\\/\\//.test(domainUrl)) {\n return `https://${domainUrl}`;\n }\n\n return domainUrl;\n};\n\n/**\n * @ignore\n */\nexport const getTokenIssuer = (\n issuer: string | undefined,\n domainUrl: string\n) => {\n if (issuer) {\n return issuer.startsWith('https://') ? issuer : `https://${issuer}/`;\n }\n\n return `${domainUrl}/`;\n};\n\nexport const parseNumber = (value: any): number | undefined => {\n if (typeof value !== 'string') {\n return value;\n }\n return parseInt(value, 10) || undefined;\n};\n\n/**\n * Ponyfill for `Object.fromEntries()`, which is not available until ES2020.\n *\n * When the target of this project reaches ES2020, this can be removed.\n */\nexport const fromEntries = <T = any>(\n iterable: Iterable<[PropertyKey, T]>\n): Record<PropertyKey, T> => {\n return [...iterable].reduce((obj, [key, val]) => {\n obj[key] = val;\n\n return obj;\n }, {} as Record<PropertyKey, T>);\n};\n","import { MissingRefreshTokenError } from '../errors';\nimport { FetchResponse } from '../global';\nimport { createQueryParams, fromEntries } from '../utils';\nimport { WorkerRefreshTokenMessage } from './worker.types';\n\nlet refreshTokens: Record<string, string> = {};\n\nconst cacheKey = (audience: string, scope: string) => `${audience}|${scope}`;\n\nconst cacheKeyContainsAudience = (audience: string, cacheKey: string) => cacheKey.startsWith(`${audience}|`);\n\nconst getRefreshToken = (audience: string, scope: string): string | undefined =>\n refreshTokens[cacheKey(audience, scope)];\n\nconst setRefreshToken = (\n refreshToken: string,\n audience: string,\n scope: string\n) => (refreshTokens[cacheKey(audience, scope)] = refreshToken);\n\nconst deleteRefreshToken = (audience: string, scope: string) =>\n delete refreshTokens[cacheKey(audience, scope)];\n\nconst wait = (time: number) =>\n new Promise<void>(resolve => setTimeout(resolve, time));\n\nconst formDataToObject = (formData: string): Record<string, any> => {\n const queryParams = new URLSearchParams(formData);\n const parsedQuery: any = {};\n\n queryParams.forEach((val, key) => {\n parsedQuery[key] = val;\n });\n\n return parsedQuery;\n};\n\nconst updateRefreshTokens = (oldRefreshToken: string | undefined, newRefreshToken: string): void => {\n Object.entries(refreshTokens).forEach(([key, token]) => {\n if (token === oldRefreshToken) {\n refreshTokens[key] = newRefreshToken;\n }\n });\n}\n\nconst checkDownscoping = (scope: string, audience: string): boolean => {\n const findCoincidence = Object.keys(refreshTokens).find((key) => {\n if (key !== 'latest_refresh_token') {\n const isSameAudience = cacheKeyContainsAudience(audience, key);\n const scopesKey = key.split('|')[1].split(\" \");\n const requestedScopes = scope.split(\" \");\n const scopesAreIncluded = requestedScopes.every((key) => scopesKey.includes(key));\n\n return isSameAudience && scopesAreIncluded;\n }\n })\n\n return findCoincidence ? true : false;\n}\n\nconst messageHandler = async ({\n data: { timeout, auth, fetchUrl, fetchOptions, useFormData, useMrrt },\n ports: [port]\n}: MessageEvent<WorkerRefreshTokenMessage>) => {\n let headers: FetchResponse['headers'] = {};\n\n let json: {\n refresh_token?: string;\n };\n let refreshToken: string | undefined;\n\n const { audience, scope } = auth || {};\n\n try {\n const body = useFormData\n ? formDataToObject(fetchOptions.body as string)\n : JSON.parse(fetchOptions.body as string);\n\n if (!body.refresh_token && body.grant_type === 'refresh_token') {\n refreshToken = getRefreshToken(audience, scope);\n\n // When we don't have any refresh_token that matches the audience and scopes\n // stored, and useMrrt is configured to true, we will use the last refresh_token\n // returned by the server to do a refresh\n // We will avoid doing MRRT if we were to downscope while doing refresh in the same audience\n if (!refreshToken && useMrrt) {\n const latestRefreshToken = refreshTokens[\"latest_refresh_token\"];\n\n const isDownscoping = checkDownscoping(scope, audience);\n\n if (latestRefreshToken && !isDownscoping) {\n refreshToken = latestRefreshToken;\n }\n }\n\n if (!refreshToken) {\n throw new MissingRefreshTokenError(audience, scope);\n }\n\n fetchOptions.body = useFormData\n ? createQueryParams({\n ...body,\n refresh_token: refreshToken\n })\n : JSON.stringify({\n ...body,\n refresh_token: refreshToken\n });\n }\n\n let abortController: AbortController | undefined;\n\n if (typeof AbortController === 'function') {\n abortController = new AbortController();\n fetchOptions.signal = abortController.signal;\n }\n\n let response: void | Response;\n\n try {\n response = await Promise.race([\n wait(timeout),\n fetch(fetchUrl, { ...fetchOptions })\n ]);\n } catch (error) {\n // fetch error, reject `sendMessage` using `error` key so that we retry.\n port.postMessage({\n error: error.message\n });\n\n return;\n }\n\n if (!response) {\n // If the request times out, abort it and let `switchFetch` raise the error.\n if (abortController) abortController.abort();\n\n port.postMessage({\n error: \"Timeout when executing 'fetch'\"\n });\n\n return;\n }\n\n headers = fromEntries(response.headers);\n json = await response.json();\n\n if (json.refresh_token) {\n // If useMrrt is configured to true we want to save the latest refresh_token\n // to be used when refreshing tokens with MRRT\n if (useMrrt) {\n refreshTokens[\"latest_refresh_token\"] = json.refresh_token;\n\n // To avoid having some refresh_token that has already been used\n // we will update those inside the list with the new one obtained\n // by the server\n updateRefreshTokens(refreshToken, json.refresh_token);\n }\n\n setRefreshToken(json.refresh_token, audience, scope);\n delete json.refresh_token;\n } else {\n deleteRefreshToken(audience, scope);\n }\n\n port.postMessage({\n ok: response.ok,\n json,\n headers\n });\n } catch (error) {\n port.postMessage({\n ok: false,\n json: {\n error: error.error,\n error_description: error.message\n },\n headers\n });\n }\n};\n\n// Don't run `addEventListener` in our tests (this is replaced in rollup)\nif (process.env.NODE_ENV === 'test') {\n module.exports = { messageHandler };\n /* c8 ignore next 4 */\n} else {\n // @ts-ignore\n addEventListener('message', messageHandler);\n}\n"],"names":["GenericError","Error","constructor","error","error_description","super","this","Object","setPrototypeOf","prototype","fromPayload","_ref","MissingRefreshTokenError","audience","scope","concat","valueOrEmptyString","value","exclude","includes","stripUndefined","params","keys","filter","k","reduce","acc","key","assign","createQueryParams","_a","clientId","client_id","__rest","URLSearchParams","toString","fromEntries","iterable","obj","val","refreshTokens","cacheKey","cacheKeyContainsAudience","startsWith","getRefreshToken","setRefreshToken","refreshToken","deleteRefreshToken","wait","time","Promise","resolve","setTimeout","formDataToObject","formData","queryParams","parsedQuery","forEach","updateRefreshTokens","oldRefreshToken","newRefreshToken","entries","token","checkDownscoping","findCoincidence","find","isSameAudience","scopesKey","split","requestedScopes","scopesAreIncluded","every","messageHandler","async","data","timeout","auth","fetchUrl","fetchOptions","useFormData","useMrrt","ports","port","_ref2","headers","json","body","JSON","parse","refresh_token","grant_type","latestRefreshToken","isDownscoping","stringify","abortController","AbortController","signal","response","race","fetch","postMessage","message","abort","ok","addEventListener"],"mappings":"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"}
1
+ {"version":3,"file":"auth0-spa-js.worker.development.js","sources":["../src/errors.ts","../src/utils.ts","../src/worker/token.worker.ts"],"sourcesContent":["/**\n * MFA requirements from an mfa_required error response\n */\nexport interface MfaRequirements {\n /** Required enrollment types */\n enroll?: Array<{ type: string }>;\n /** Required challenge types */\n challenge?: Array<{ type: string }>;\n}\n\n/**\n * Thrown when network requests to the Auth server fail.\n */\nexport class GenericError extends Error {\n constructor(public error: string, public error_description: string) {\n super(error_description);\n Object.setPrototypeOf(this, GenericError.prototype);\n }\n\n static fromPayload({\n error,\n error_description\n }: {\n error: string;\n error_description: string;\n }) {\n return new GenericError(error, error_description);\n }\n}\n\n/**\n * Thrown when handling the redirect callback fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class AuthenticationError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Thrown when handling the redirect callback for the connect flow fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class ConnectError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public connection: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, ConnectError.prototype);\n }\n}\n\n/**\n * Thrown when silent auth times out (usually due to a configuration issue) or\n * when network requests to the Auth server timeout.\n */\nexport class TimeoutError extends GenericError {\n constructor() {\n super('timeout', 'Timeout');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\n/**\n * Error thrown when the login popup times out (if the user does not complete auth)\n */\nexport class PopupTimeoutError extends TimeoutError {\n constructor(public popup: Window) {\n super();\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupTimeoutError.prototype);\n }\n}\n\nexport class PopupCancelledError extends GenericError {\n constructor(public popup: Window) {\n super('cancelled', 'Popup closed');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupCancelledError.prototype);\n }\n}\n\nexport class PopupOpenError extends GenericError {\n constructor() {\n super('popup_open', 'Unable to open a popup for loginWithPopup - window.open returned `null`');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupOpenError.prototype);\n }\n}\n\n/**\n * Error thrown when the token exchange results in a `mfa_required` error\n */\nexport class MfaRequiredError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public mfa_token: string,\n public mfa_requirements: MfaRequirements\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, MfaRequiredError.prototype);\n }\n}\n\n/**\n * Error thrown when there is no refresh token to use\n */\nexport class MissingRefreshTokenError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_refresh_token',\n `Missing Refresh Token (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingRefreshTokenError.prototype);\n }\n}\n\n/**\n * Error thrown when there are missing scopes after refreshing a token\n */\nexport class MissingScopesError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_scopes',\n `Missing requested scopes after refresh (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', missing scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingScopesError.prototype);\n }\n}\n\n/**\n * Error thrown when the wrong DPoP nonce is used and a potential subsequent retry wasn't able to fix it.\n */\nexport class UseDpopNonceError extends GenericError {\n constructor(public newDpopNonce: string | undefined) {\n super('use_dpop_nonce', 'Server rejected DPoP proof: wrong nonce');\n\n Object.setPrototypeOf(this, UseDpopNonceError.prototype);\n }\n}\n\n/**\n * Returns an empty string when value is falsy, or when it's value is included in the exclude argument.\n * @param value The value to check\n * @param exclude An array of values that should result in an empty string.\n * @returns The value, or an empty string when falsy or included in the exclude argument.\n */\nfunction valueOrEmptyString(value: string, exclude: string[] = []) {\n return value && !exclude.includes(value) ? value : '';\n}\n","import { AuthenticationResult, PopupConfigOptions } from './global';\n\nimport {\n DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS,\n CLEANUP_IFRAME_TIMEOUT_IN_SECONDS\n} from './constants';\n\nimport {\n PopupTimeoutError,\n TimeoutError,\n GenericError,\n PopupCancelledError\n} from './errors';\n\nexport const parseAuthenticationResult = (\n queryString: string\n): AuthenticationResult => {\n if (queryString.indexOf('#') > -1) {\n queryString = queryString.substring(0, queryString.indexOf('#'));\n }\n\n const searchParams = new URLSearchParams(queryString);\n\n return {\n state: searchParams.get('state')!,\n code: searchParams.get('code') || undefined,\n connect_code: searchParams.get('connect_code') || undefined,\n error: searchParams.get('error') || undefined,\n error_description: searchParams.get('error_description') || undefined\n };\n};\n\nexport const runIframe = (\n authorizeUrl: string,\n eventOrigin: string,\n timeoutInSeconds: number = DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS\n) => {\n return new Promise<AuthenticationResult>((res, rej) => {\n const iframe = window.document.createElement('iframe');\n\n iframe.setAttribute('width', '0');\n iframe.setAttribute('height', '0');\n iframe.style.display = 'none';\n\n const removeIframe = () => {\n if (window.document.body.contains(iframe)) {\n window.document.body.removeChild(iframe);\n window.removeEventListener('message', iframeEventHandler, false);\n }\n };\n\n let iframeEventHandler: (e: MessageEvent) => void;\n\n const timeoutSetTimeoutId = setTimeout(() => {\n rej(new TimeoutError());\n removeIframe();\n }, timeoutInSeconds * 1000);\n\n iframeEventHandler = function (e: MessageEvent) {\n if (e.origin != eventOrigin) return;\n if (!e.data || e.data.type !== 'authorization_response') return;\n\n const eventSource = e.source;\n\n if (eventSource) {\n (eventSource as any).close();\n }\n\n e.data.response.error\n ? rej(GenericError.fromPayload(e.data.response))\n : res(e.data.response);\n\n clearTimeout(timeoutSetTimeoutId);\n window.removeEventListener('message', iframeEventHandler, false);\n\n // Delay the removal of the iframe to prevent hanging loading status\n // in Chrome: https://github.com/auth0/auth0-spa-js/issues/240\n setTimeout(removeIframe, CLEANUP_IFRAME_TIMEOUT_IN_SECONDS * 1000);\n };\n\n window.addEventListener('message', iframeEventHandler, false);\n window.document.body.appendChild(iframe);\n iframe.setAttribute('src', authorizeUrl);\n });\n};\n\nexport const openPopup = (url: string) => {\n const width = 400;\n const height = 600;\n const left = window.screenX + (window.innerWidth - width) / 2;\n const top = window.screenY + (window.innerHeight - height) / 2;\n\n return window.open(\n url,\n 'auth0:authorize:popup',\n `left=${left},top=${top},width=${width},height=${height},resizable,scrollbars=yes,status=1`\n );\n};\n\nexport const runPopup = (config: PopupConfigOptions) => {\n return new Promise<AuthenticationResult>((resolve, reject) => {\n let popupEventListener: (e: MessageEvent) => void;\n\n // Check each second if the popup is closed triggering a PopupCancelledError\n const popupTimer = setInterval(() => {\n if (config.popup && config.popup.closed) {\n clearInterval(popupTimer);\n clearTimeout(timeoutId);\n window.removeEventListener('message', popupEventListener, false);\n reject(new PopupCancelledError(config.popup));\n }\n }, 1000);\n\n const timeoutId = setTimeout(() => {\n clearInterval(popupTimer);\n reject(new PopupTimeoutError(config.popup));\n window.removeEventListener('message', popupEventListener, false);\n }, (config.timeoutInSeconds || DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS) * 1000);\n\n popupEventListener = function (e: MessageEvent) {\n if (!e.data || e.data.type !== 'authorization_response') {\n return;\n }\n\n clearTimeout(timeoutId);\n clearInterval(popupTimer);\n window.removeEventListener('message', popupEventListener, false);\n\n // Close popup automatically unless closePopup is explicitly set to false\n if (config.closePopup !== false) {\n config.popup.close();\n }\n\n if (e.data.response.error) {\n return reject(GenericError.fromPayload(e.data.response));\n }\n\n resolve(e.data.response);\n };\n\n window.addEventListener('message', popupEventListener);\n });\n};\n\nexport const getCrypto = () => {\n return window.crypto;\n};\n\nexport const createRandomString = () => {\n const charset =\n '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.';\n const validMax = 256 - (256 % charset.length);\n let random = '';\n while (random.length < 43) {\n const bytes = getCrypto().getRandomValues(new Uint8Array(43 - random.length));\n for (const byte of bytes) {\n if (random.length < 43 && byte < validMax) {\n random += charset[byte % charset.length];\n }\n }\n }\n return random;\n};\n\nexport const encode = (value: string) => btoa(value);\nexport const decode = (value: string) => atob(value);\n\nconst stripUndefined = (params: any) => {\n return Object.keys(params)\n .filter(k => typeof params[k] !== 'undefined')\n .reduce((acc, key) => ({ ...acc, [key]: params[key] }), {});\n};\n\nconst ALLOWED_AUTH0CLIENT_PROPERTIES = [\n {\n key: 'name',\n type: ['string']\n },\n {\n key: 'version',\n type: ['string', 'number']\n },\n {\n key: 'env',\n type: ['object']\n }\n];\n\n/**\n * Strips any property that is not present in ALLOWED_AUTH0CLIENT_PROPERTIES\n * @param auth0Client - The full auth0Client object\n * @param excludeEnv - If true, excludes the 'env' property from the result\n * @returns The stripped auth0Client object\n */\nexport const stripAuth0Client = (auth0Client: any, excludeEnv = false) => {\n return Object.keys(auth0Client).reduce((acc: any, key: string) => {\n // Exclude 'env' if requested (for /authorize query params to prevent truncation)\n if (excludeEnv && key === 'env') {\n return acc;\n }\n\n const allowedProperty = ALLOWED_AUTH0CLIENT_PROPERTIES.find(\n p => p.key === key\n );\n if (\n allowedProperty &&\n allowedProperty.type.includes(typeof auth0Client[key])\n ) {\n acc[key] = auth0Client[key];\n }\n\n return acc;\n }, {});\n};\n\nexport const createQueryParams = ({ clientId: client_id, ...params }: any) => {\n return new URLSearchParams(\n stripUndefined({ client_id, ...params })\n ).toString();\n};\n\nexport const sha256 = async (s: string) => {\n const digestOp: any = getCrypto().subtle.digest(\n { name: 'SHA-256' },\n new TextEncoder().encode(s)\n );\n\n return await digestOp;\n};\n\nconst urlEncodeB64 = (input: string) => {\n const b64Chars: { [index: string]: string } = { '+': '-', '/': '_', '=': '' };\n return input.replace(/[+/=]/g, (m: string) => b64Chars[m]);\n};\n\n// https://stackoverflow.com/questions/30106476/\nconst decodeB64 = (input: string) =>\n decodeURIComponent(\n atob(input)\n .split('')\n .map(c => {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join('')\n );\n\nexport const urlDecodeB64 = (input: string) =>\n decodeB64(input.replace(/_/g, '/').replace(/-/g, '+'));\n\nexport const bufferToBase64UrlEncoded = (input: number[] | Uint8Array) => {\n const ie11SafeInput = new Uint8Array(input);\n return urlEncodeB64(\n window.btoa(String.fromCharCode(...Array.from(ie11SafeInput)))\n );\n};\n\nexport const validateCrypto = () => {\n if (!getCrypto()) {\n throw new Error(\n 'For security reasons, `window.crypto` is required to run `auth0-spa-js`.'\n );\n }\n if (typeof getCrypto().subtle === 'undefined') {\n throw new Error(`\n auth0-spa-js must run on a secure origin. See https://github.com/auth0/auth0-spa-js/blob/main/FAQ.md#why-do-i-get-auth0-spa-js-must-run-on-a-secure-origin for more information.\n `);\n }\n};\n\n/**\n * @ignore\n */\nexport const getDomain = (domainUrl: string) => {\n if (!/^https?:\\/\\//.test(domainUrl)) {\n return `https://${domainUrl}`;\n }\n\n return domainUrl;\n};\n\n/**\n * @ignore\n */\nexport const getTokenIssuer = (\n issuer: string | undefined,\n domainUrl: string\n) => {\n if (issuer) {\n return issuer.startsWith('https://') ? issuer : `https://${issuer}/`;\n }\n\n return `${domainUrl}/`;\n};\n\nexport const parseNumber = (value: any): number | undefined => {\n if (typeof value !== 'string') {\n return value;\n }\n return parseInt(value, 10) || undefined;\n};\n\n/**\n * Ponyfill for `Object.fromEntries()`, which is not available until ES2020.\n *\n * When the target of this project reaches ES2020, this can be removed.\n */\nexport const fromEntries = <T = any>(\n iterable: Iterable<[PropertyKey, T]>\n): Record<PropertyKey, T> => {\n return [...iterable].reduce((obj, [key, val]) => {\n obj[key] = val;\n\n return obj;\n }, {} as Record<PropertyKey, T>);\n};\n","import { MissingRefreshTokenError } from '../errors';\nimport { FetchResponse } from '../global';\nimport { createQueryParams, fromEntries } from '../utils';\nimport { WorkerRefreshTokenMessage } from './worker.types';\n\nlet refreshTokens: Record<string, string> = {};\n\nconst cacheKey = (audience: string, scope: string) => `${audience}|${scope}`;\n\nconst cacheKeyContainsAudience = (audience: string, cacheKey: string) => cacheKey.startsWith(`${audience}|`);\n\nconst getRefreshToken = (audience: string, scope: string): string | undefined =>\n refreshTokens[cacheKey(audience, scope)];\n\nconst setRefreshToken = (\n refreshToken: string,\n audience: string,\n scope: string\n) => (refreshTokens[cacheKey(audience, scope)] = refreshToken);\n\nconst deleteRefreshToken = (audience: string, scope: string) =>\n delete refreshTokens[cacheKey(audience, scope)];\n\nconst wait = (time: number) =>\n new Promise<void>(resolve => setTimeout(resolve, time));\n\nconst formDataToObject = (formData: string): Record<string, any> => {\n const queryParams = new URLSearchParams(formData);\n const parsedQuery: any = {};\n\n queryParams.forEach((val, key) => {\n parsedQuery[key] = val;\n });\n\n return parsedQuery;\n};\n\nconst updateRefreshTokens = (oldRefreshToken: string | undefined, newRefreshToken: string): void => {\n Object.entries(refreshTokens).forEach(([key, token]) => {\n if (token === oldRefreshToken) {\n refreshTokens[key] = newRefreshToken;\n }\n });\n}\n\nconst checkDownscoping = (scope: string, audience: string): boolean => {\n const findCoincidence = Object.keys(refreshTokens).find((key) => {\n if (key !== 'latest_refresh_token') {\n const isSameAudience = cacheKeyContainsAudience(audience, key);\n const scopesKey = key.split('|')[1].split(\" \");\n const requestedScopes = scope.split(\" \");\n const scopesAreIncluded = requestedScopes.every((key) => scopesKey.includes(key));\n\n return isSameAudience && scopesAreIncluded;\n }\n })\n\n return findCoincidence ? true : false;\n}\n\nconst messageHandler = async ({\n data: { timeout, auth, fetchUrl, fetchOptions, useFormData, useMrrt },\n ports: [port]\n}: MessageEvent<WorkerRefreshTokenMessage>) => {\n let headers: FetchResponse['headers'] = {};\n\n let json: {\n refresh_token?: string;\n };\n let refreshToken: string | undefined;\n\n const { audience, scope } = auth || {};\n\n try {\n const body = useFormData\n ? formDataToObject(fetchOptions.body as string)\n : JSON.parse(fetchOptions.body as string);\n\n if (!body.refresh_token && body.grant_type === 'refresh_token') {\n refreshToken = getRefreshToken(audience, scope);\n\n // When we don't have any refresh_token that matches the audience and scopes\n // stored, and useMrrt is configured to true, we will use the last refresh_token\n // returned by the server to do a refresh\n // We will avoid doing MRRT if we were to downscope while doing refresh in the same audience\n if (!refreshToken && useMrrt) {\n const latestRefreshToken = refreshTokens[\"latest_refresh_token\"];\n\n const isDownscoping = checkDownscoping(scope, audience);\n\n if (latestRefreshToken && !isDownscoping) {\n refreshToken = latestRefreshToken;\n }\n }\n\n if (!refreshToken) {\n throw new MissingRefreshTokenError(audience, scope);\n }\n\n fetchOptions.body = useFormData\n ? createQueryParams({\n ...body,\n refresh_token: refreshToken\n })\n : JSON.stringify({\n ...body,\n refresh_token: refreshToken\n });\n }\n\n let abortController: AbortController | undefined;\n\n if (typeof AbortController === 'function') {\n abortController = new AbortController();\n fetchOptions.signal = abortController.signal;\n }\n\n let response: void | Response;\n\n try {\n response = await Promise.race([\n wait(timeout),\n fetch(fetchUrl, { ...fetchOptions })\n ]);\n } catch (error) {\n // fetch error, reject `sendMessage` using `error` key so that we retry.\n port.postMessage({\n error: error.message\n });\n\n return;\n }\n\n if (!response) {\n // If the request times out, abort it and let `switchFetch` raise the error.\n if (abortController) abortController.abort();\n\n port.postMessage({\n error: \"Timeout when executing 'fetch'\"\n });\n\n return;\n }\n\n headers = fromEntries(response.headers);\n json = await response.json();\n\n if (json.refresh_token) {\n // If useMrrt is configured to true we want to save the latest refresh_token\n // to be used when refreshing tokens with MRRT\n if (useMrrt) {\n refreshTokens[\"latest_refresh_token\"] = json.refresh_token;\n\n // To avoid having some refresh_token that has already been used\n // we will update those inside the list with the new one obtained\n // by the server\n updateRefreshTokens(refreshToken, json.refresh_token);\n }\n\n setRefreshToken(json.refresh_token, audience, scope);\n delete json.refresh_token;\n } else {\n deleteRefreshToken(audience, scope);\n }\n\n port.postMessage({\n ok: response.ok,\n json,\n headers\n });\n } catch (error) {\n port.postMessage({\n ok: false,\n json: {\n error: error.error,\n error_description: error.message\n },\n headers\n });\n }\n};\n\n// Don't run `addEventListener` in our tests (this is replaced in rollup)\nif (process.env.NODE_ENV === 'test') {\n module.exports = { messageHandler };\n /* c8 ignore next 4 */\n} else {\n // @ts-ignore\n addEventListener('message', messageHandler);\n}\n"],"names":["GenericError","Error","constructor","error","error_description","super","this","Object","setPrototypeOf","prototype","fromPayload","_ref","MissingRefreshTokenError","audience","scope","concat","valueOrEmptyString","value","exclude","includes","stripUndefined","params","keys","filter","k","reduce","acc","key","assign","createQueryParams","_a","clientId","client_id","__rest","URLSearchParams","toString","fromEntries","iterable","obj","val","refreshTokens","cacheKey","cacheKeyContainsAudience","startsWith","getRefreshToken","setRefreshToken","refreshToken","deleteRefreshToken","wait","time","Promise","resolve","setTimeout","formDataToObject","formData","queryParams","parsedQuery","forEach","updateRefreshTokens","oldRefreshToken","newRefreshToken","entries","token","checkDownscoping","findCoincidence","find","isSameAudience","scopesKey","split","requestedScopes","scopesAreIncluded","every","messageHandler","async","data","timeout","auth","fetchUrl","fetchOptions","useFormData","useMrrt","ports","port","_ref2","headers","json","body","JSON","parse","refresh_token","grant_type","latestRefreshToken","isDownscoping","stringify","abortController","AbortController","signal","response","race","fetch","postMessage","message","abort","ok","addEventListener"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth0-spa-js.worker.production.js","sources":["../src/errors.ts","../src/utils.ts","../src/worker/token.worker.ts"],"sourcesContent":["/**\n * MFA requirements from an mfa_required error response\n */\nexport interface MfaRequirements {\n /** Required enrollment types */\n enroll?: Array<{ type: string }>;\n /** Required challenge types */\n challenge?: Array<{ type: string }>;\n}\n\n/**\n * Thrown when network requests to the Auth server fail.\n */\nexport class GenericError extends Error {\n constructor(public error: string, public error_description: string) {\n super(error_description);\n Object.setPrototypeOf(this, GenericError.prototype);\n }\n\n static fromPayload({\n error,\n error_description\n }: {\n error: string;\n error_description: string;\n }) {\n return new GenericError(error, error_description);\n }\n}\n\n/**\n * Thrown when handling the redirect callback fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class AuthenticationError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Thrown when handling the redirect callback for the connect flow fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class ConnectError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public connection: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, ConnectError.prototype);\n }\n}\n\n/**\n * Thrown when silent auth times out (usually due to a configuration issue) or\n * when network requests to the Auth server timeout.\n */\nexport class TimeoutError extends GenericError {\n constructor() {\n super('timeout', 'Timeout');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\n/**\n * Error thrown when the login popup times out (if the user does not complete auth)\n */\nexport class PopupTimeoutError extends TimeoutError {\n constructor(public popup: Window) {\n super();\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupTimeoutError.prototype);\n }\n}\n\nexport class PopupCancelledError extends GenericError {\n constructor(public popup: Window) {\n super('cancelled', 'Popup closed');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupCancelledError.prototype);\n }\n}\n\nexport class PopupOpenError extends GenericError {\n constructor() {\n super('popup_open', 'Unable to open a popup for loginWithPopup - window.open returned `null`');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupOpenError.prototype);\n }\n}\n\n/**\n * Error thrown when the token exchange results in a `mfa_required` error\n */\nexport class MfaRequiredError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public mfa_token: string,\n public mfa_requirements: MfaRequirements\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, MfaRequiredError.prototype);\n }\n}\n\n/**\n * Error thrown when there is no refresh token to use\n */\nexport class MissingRefreshTokenError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_refresh_token',\n `Missing Refresh Token (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingRefreshTokenError.prototype);\n }\n}\n\n/**\n * Error thrown when there are missing scopes after refreshing a token\n */\nexport class MissingScopesError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_scopes',\n `Missing requested scopes after refresh (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', missing scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingScopesError.prototype);\n }\n}\n\n/**\n * Error thrown when the wrong DPoP nonce is used and a potential subsequent retry wasn't able to fix it.\n */\nexport class UseDpopNonceError extends GenericError {\n constructor(public newDpopNonce: string | undefined) {\n super('use_dpop_nonce', 'Server rejected DPoP proof: wrong nonce');\n\n Object.setPrototypeOf(this, UseDpopNonceError.prototype);\n }\n}\n\n/**\n * Returns an empty string when value is falsy, or when it's value is included in the exclude argument.\n * @param value The value to check\n * @param exclude An array of values that should result in an empty string.\n * @returns The value, or an empty string when falsy or included in the exclude argument.\n */\nfunction valueOrEmptyString(value: string, exclude: string[] = []) {\n return value && !exclude.includes(value) ? value : '';\n}\n","import { AuthenticationResult, PopupConfigOptions } from './global';\n\nimport {\n DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS,\n CLEANUP_IFRAME_TIMEOUT_IN_SECONDS\n} from './constants';\n\nimport {\n PopupTimeoutError,\n TimeoutError,\n GenericError,\n PopupCancelledError\n} from './errors';\n\nexport const parseAuthenticationResult = (\n queryString: string\n): AuthenticationResult => {\n if (queryString.indexOf('#') > -1) {\n queryString = queryString.substring(0, queryString.indexOf('#'));\n }\n\n const searchParams = new URLSearchParams(queryString);\n\n return {\n state: searchParams.get('state')!,\n code: searchParams.get('code') || undefined,\n connect_code: searchParams.get('connect_code') || undefined,\n error: searchParams.get('error') || undefined,\n error_description: searchParams.get('error_description') || undefined\n };\n};\n\nexport const runIframe = (\n authorizeUrl: string,\n eventOrigin: string,\n timeoutInSeconds: number = DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS\n) => {\n return new Promise<AuthenticationResult>((res, rej) => {\n const iframe = window.document.createElement('iframe');\n\n iframe.setAttribute('width', '0');\n iframe.setAttribute('height', '0');\n iframe.style.display = 'none';\n\n const removeIframe = () => {\n if (window.document.body.contains(iframe)) {\n window.document.body.removeChild(iframe);\n window.removeEventListener('message', iframeEventHandler, false);\n }\n };\n\n let iframeEventHandler: (e: MessageEvent) => void;\n\n const timeoutSetTimeoutId = setTimeout(() => {\n rej(new TimeoutError());\n removeIframe();\n }, timeoutInSeconds * 1000);\n\n iframeEventHandler = function (e: MessageEvent) {\n if (e.origin != eventOrigin) return;\n if (!e.data || e.data.type !== 'authorization_response') return;\n\n const eventSource = e.source;\n\n if (eventSource) {\n (eventSource as any).close();\n }\n\n e.data.response.error\n ? rej(GenericError.fromPayload(e.data.response))\n : res(e.data.response);\n\n clearTimeout(timeoutSetTimeoutId);\n window.removeEventListener('message', iframeEventHandler, false);\n\n // Delay the removal of the iframe to prevent hanging loading status\n // in Chrome: https://github.com/auth0/auth0-spa-js/issues/240\n setTimeout(removeIframe, CLEANUP_IFRAME_TIMEOUT_IN_SECONDS * 1000);\n };\n\n window.addEventListener('message', iframeEventHandler, false);\n window.document.body.appendChild(iframe);\n iframe.setAttribute('src', authorizeUrl);\n });\n};\n\nexport const openPopup = (url: string) => {\n const width = 400;\n const height = 600;\n const left = window.screenX + (window.innerWidth - width) / 2;\n const top = window.screenY + (window.innerHeight - height) / 2;\n\n return window.open(\n url,\n 'auth0:authorize:popup',\n `left=${left},top=${top},width=${width},height=${height},resizable,scrollbars=yes,status=1`\n );\n};\n\nexport const runPopup = (config: PopupConfigOptions) => {\n return new Promise<AuthenticationResult>((resolve, reject) => {\n let popupEventListener: (e: MessageEvent) => void;\n\n // Check each second if the popup is closed triggering a PopupCancelledError\n const popupTimer = setInterval(() => {\n if (config.popup && config.popup.closed) {\n clearInterval(popupTimer);\n clearTimeout(timeoutId);\n window.removeEventListener('message', popupEventListener, false);\n reject(new PopupCancelledError(config.popup));\n }\n }, 1000);\n\n const timeoutId = setTimeout(() => {\n clearInterval(popupTimer);\n reject(new PopupTimeoutError(config.popup));\n window.removeEventListener('message', popupEventListener, false);\n }, (config.timeoutInSeconds || DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS) * 1000);\n\n popupEventListener = function (e: MessageEvent) {\n if (!e.data || e.data.type !== 'authorization_response') {\n return;\n }\n\n clearTimeout(timeoutId);\n clearInterval(popupTimer);\n window.removeEventListener('message', popupEventListener, false);\n\n // Close popup automatically unless closePopup is explicitly set to false\n if (config.closePopup !== false) {\n config.popup.close();\n }\n\n if (e.data.response.error) {\n return reject(GenericError.fromPayload(e.data.response));\n }\n\n resolve(e.data.response);\n };\n\n window.addEventListener('message', popupEventListener);\n });\n};\n\nexport const getCrypto = () => {\n return window.crypto;\n};\n\nexport const createRandomString = () => {\n const charset =\n '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.';\n let random = '';\n const randomValues = Array.from(\n getCrypto().getRandomValues(new Uint8Array(43))\n );\n randomValues.forEach(v => (random += charset[v % charset.length]));\n return random;\n};\n\nexport const encode = (value: string) => btoa(value);\nexport const decode = (value: string) => atob(value);\n\nconst stripUndefined = (params: any) => {\n return Object.keys(params)\n .filter(k => typeof params[k] !== 'undefined')\n .reduce((acc, key) => ({ ...acc, [key]: params[key] }), {});\n};\n\nconst ALLOWED_AUTH0CLIENT_PROPERTIES = [\n {\n key: 'name',\n type: ['string']\n },\n {\n key: 'version',\n type: ['string', 'number']\n },\n {\n key: 'env',\n type: ['object']\n }\n];\n\n/**\n * Strips any property that is not present in ALLOWED_AUTH0CLIENT_PROPERTIES\n * @param auth0Client - The full auth0Client object\n * @param excludeEnv - If true, excludes the 'env' property from the result\n * @returns The stripped auth0Client object\n */\nexport const stripAuth0Client = (auth0Client: any, excludeEnv = false) => {\n return Object.keys(auth0Client).reduce((acc: any, key: string) => {\n // Exclude 'env' if requested (for /authorize query params to prevent truncation)\n if (excludeEnv && key === 'env') {\n return acc;\n }\n\n const allowedProperty = ALLOWED_AUTH0CLIENT_PROPERTIES.find(\n p => p.key === key\n );\n if (\n allowedProperty &&\n allowedProperty.type.includes(typeof auth0Client[key])\n ) {\n acc[key] = auth0Client[key];\n }\n\n return acc;\n }, {});\n};\n\nexport const createQueryParams = ({ clientId: client_id, ...params }: any) => {\n return new URLSearchParams(\n stripUndefined({ client_id, ...params })\n ).toString();\n};\n\nexport const sha256 = async (s: string) => {\n const digestOp: any = getCrypto().subtle.digest(\n { name: 'SHA-256' },\n new TextEncoder().encode(s)\n );\n\n return await digestOp;\n};\n\nconst urlEncodeB64 = (input: string) => {\n const b64Chars: { [index: string]: string } = { '+': '-', '/': '_', '=': '' };\n return input.replace(/[+/=]/g, (m: string) => b64Chars[m]);\n};\n\n// https://stackoverflow.com/questions/30106476/\nconst decodeB64 = (input: string) =>\n decodeURIComponent(\n atob(input)\n .split('')\n .map(c => {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join('')\n );\n\nexport const urlDecodeB64 = (input: string) =>\n decodeB64(input.replace(/_/g, '/').replace(/-/g, '+'));\n\nexport const bufferToBase64UrlEncoded = (input: number[] | Uint8Array) => {\n const ie11SafeInput = new Uint8Array(input);\n return urlEncodeB64(\n window.btoa(String.fromCharCode(...Array.from(ie11SafeInput)))\n );\n};\n\nexport const validateCrypto = () => {\n if (!getCrypto()) {\n throw new Error(\n 'For security reasons, `window.crypto` is required to run `auth0-spa-js`.'\n );\n }\n if (typeof getCrypto().subtle === 'undefined') {\n throw new Error(`\n auth0-spa-js must run on a secure origin. See https://github.com/auth0/auth0-spa-js/blob/main/FAQ.md#why-do-i-get-auth0-spa-js-must-run-on-a-secure-origin for more information.\n `);\n }\n};\n\n/**\n * @ignore\n */\nexport const getDomain = (domainUrl: string) => {\n if (!/^https?:\\/\\//.test(domainUrl)) {\n return `https://${domainUrl}`;\n }\n\n return domainUrl;\n};\n\n/**\n * @ignore\n */\nexport const getTokenIssuer = (\n issuer: string | undefined,\n domainUrl: string\n) => {\n if (issuer) {\n return issuer.startsWith('https://') ? issuer : `https://${issuer}/`;\n }\n\n return `${domainUrl}/`;\n};\n\nexport const parseNumber = (value: any): number | undefined => {\n if (typeof value !== 'string') {\n return value;\n }\n return parseInt(value, 10) || undefined;\n};\n\n/**\n * Ponyfill for `Object.fromEntries()`, which is not available until ES2020.\n *\n * When the target of this project reaches ES2020, this can be removed.\n */\nexport const fromEntries = <T = any>(\n iterable: Iterable<[PropertyKey, T]>\n): Record<PropertyKey, T> => {\n return [...iterable].reduce((obj, [key, val]) => {\n obj[key] = val;\n\n return obj;\n }, {} as Record<PropertyKey, T>);\n};\n","import { MissingRefreshTokenError } from '../errors';\nimport { FetchResponse } from '../global';\nimport { createQueryParams, fromEntries } from '../utils';\nimport { WorkerRefreshTokenMessage } from './worker.types';\n\nlet refreshTokens: Record<string, string> = {};\n\nconst cacheKey = (audience: string, scope: string) => `${audience}|${scope}`;\n\nconst cacheKeyContainsAudience = (audience: string, cacheKey: string) => cacheKey.startsWith(`${audience}|`);\n\nconst getRefreshToken = (audience: string, scope: string): string | undefined =>\n refreshTokens[cacheKey(audience, scope)];\n\nconst setRefreshToken = (\n refreshToken: string,\n audience: string,\n scope: string\n) => (refreshTokens[cacheKey(audience, scope)] = refreshToken);\n\nconst deleteRefreshToken = (audience: string, scope: string) =>\n delete refreshTokens[cacheKey(audience, scope)];\n\nconst wait = (time: number) =>\n new Promise<void>(resolve => setTimeout(resolve, time));\n\nconst formDataToObject = (formData: string): Record<string, any> => {\n const queryParams = new URLSearchParams(formData);\n const parsedQuery: any = {};\n\n queryParams.forEach((val, key) => {\n parsedQuery[key] = val;\n });\n\n return parsedQuery;\n};\n\nconst updateRefreshTokens = (oldRefreshToken: string | undefined, newRefreshToken: string): void => {\n Object.entries(refreshTokens).forEach(([key, token]) => {\n if (token === oldRefreshToken) {\n refreshTokens[key] = newRefreshToken;\n }\n });\n}\n\nconst checkDownscoping = (scope: string, audience: string): boolean => {\n const findCoincidence = Object.keys(refreshTokens).find((key) => {\n if (key !== 'latest_refresh_token') {\n const isSameAudience = cacheKeyContainsAudience(audience, key);\n const scopesKey = key.split('|')[1].split(\" \");\n const requestedScopes = scope.split(\" \");\n const scopesAreIncluded = requestedScopes.every((key) => scopesKey.includes(key));\n\n return isSameAudience && scopesAreIncluded;\n }\n })\n\n return findCoincidence ? true : false;\n}\n\nconst messageHandler = async ({\n data: { timeout, auth, fetchUrl, fetchOptions, useFormData, useMrrt },\n ports: [port]\n}: MessageEvent<WorkerRefreshTokenMessage>) => {\n let headers: FetchResponse['headers'] = {};\n\n let json: {\n refresh_token?: string;\n };\n let refreshToken: string | undefined;\n\n const { audience, scope } = auth || {};\n\n try {\n const body = useFormData\n ? formDataToObject(fetchOptions.body as string)\n : JSON.parse(fetchOptions.body as string);\n\n if (!body.refresh_token && body.grant_type === 'refresh_token') {\n refreshToken = getRefreshToken(audience, scope);\n\n // When we don't have any refresh_token that matches the audience and scopes\n // stored, and useMrrt is configured to true, we will use the last refresh_token\n // returned by the server to do a refresh\n // We will avoid doing MRRT if we were to downscope while doing refresh in the same audience\n if (!refreshToken && useMrrt) {\n const latestRefreshToken = refreshTokens[\"latest_refresh_token\"];\n\n const isDownscoping = checkDownscoping(scope, audience);\n\n if (latestRefreshToken && !isDownscoping) {\n refreshToken = latestRefreshToken;\n }\n }\n\n if (!refreshToken) {\n throw new MissingRefreshTokenError(audience, scope);\n }\n\n fetchOptions.body = useFormData\n ? createQueryParams({\n ...body,\n refresh_token: refreshToken\n })\n : JSON.stringify({\n ...body,\n refresh_token: refreshToken\n });\n }\n\n let abortController: AbortController | undefined;\n\n if (typeof AbortController === 'function') {\n abortController = new AbortController();\n fetchOptions.signal = abortController.signal;\n }\n\n let response: void | Response;\n\n try {\n response = await Promise.race([\n wait(timeout),\n fetch(fetchUrl, { ...fetchOptions })\n ]);\n } catch (error) {\n // fetch error, reject `sendMessage` using `error` key so that we retry.\n port.postMessage({\n error: error.message\n });\n\n return;\n }\n\n if (!response) {\n // If the request times out, abort it and let `switchFetch` raise the error.\n if (abortController) abortController.abort();\n\n port.postMessage({\n error: \"Timeout when executing 'fetch'\"\n });\n\n return;\n }\n\n headers = fromEntries(response.headers);\n json = await response.json();\n\n if (json.refresh_token) {\n // If useMrrt is configured to true we want to save the latest refresh_token\n // to be used when refreshing tokens with MRRT\n if (useMrrt) {\n refreshTokens[\"latest_refresh_token\"] = json.refresh_token;\n\n // To avoid having some refresh_token that has already been used\n // we will update those inside the list with the new one obtained\n // by the server\n updateRefreshTokens(refreshToken, json.refresh_token);\n }\n\n setRefreshToken(json.refresh_token, audience, scope);\n delete json.refresh_token;\n } else {\n deleteRefreshToken(audience, scope);\n }\n\n port.postMessage({\n ok: response.ok,\n json,\n headers\n });\n } catch (error) {\n port.postMessage({\n ok: false,\n json: {\n error: error.error,\n error_description: error.message\n },\n headers\n });\n }\n};\n\n// Don't run `addEventListener` in our tests (this is replaced in rollup)\nif (process.env.NODE_ENV === 'test') {\n module.exports = { messageHandler };\n /* c8 ignore next 4 */\n} else {\n // @ts-ignore\n addEventListener('message', messageHandler);\n}\n"],"names":["GenericError","Error","constructor","error","error_description","super","this","Object","setPrototypeOf","prototype","fromPayload","_ref","MissingRefreshTokenError","audience","scope","concat","valueOrEmptyString","value","includes","createQueryParams","_a","clientId","client_id","params","__rest","URLSearchParams","keys","filter","k","reduce","acc","key","assign","stripUndefined","toString","refreshTokens","cacheKey","addEventListener","async","json","refreshToken","data","timeout","auth","fetchUrl","fetchOptions","useFormData","useMrrt","ports","port","_ref2","headers","body","formData","queryParams","parsedQuery","forEach","val","formDataToObject","JSON","parse","refresh_token","grant_type","getRefreshToken","latestRefreshToken","isDownscoping","checkDownscoping","findCoincidence","find","isSameAudience","cacheKeyContainsAudience","startsWith","scopesKey","split","scopesAreIncluded","every","stringify","abortController","response","AbortController","signal","Promise","race","time","resolve","setTimeout","fetch","postMessage","message","abort","iterable","obj","oldRefreshToken","newRefreshToken","entries","token","setRefreshToken","deleteRefreshToken","ok","updateRefreshTokens"],"mappings":"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"}
1
+ {"version":3,"file":"auth0-spa-js.worker.production.js","sources":["../src/errors.ts","../src/utils.ts","../src/worker/token.worker.ts"],"sourcesContent":["/**\n * MFA requirements from an mfa_required error response\n */\nexport interface MfaRequirements {\n /** Required enrollment types */\n enroll?: Array<{ type: string }>;\n /** Required challenge types */\n challenge?: Array<{ type: string }>;\n}\n\n/**\n * Thrown when network requests to the Auth server fail.\n */\nexport class GenericError extends Error {\n constructor(public error: string, public error_description: string) {\n super(error_description);\n Object.setPrototypeOf(this, GenericError.prototype);\n }\n\n static fromPayload({\n error,\n error_description\n }: {\n error: string;\n error_description: string;\n }) {\n return new GenericError(error, error_description);\n }\n}\n\n/**\n * Thrown when handling the redirect callback fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class AuthenticationError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Thrown when handling the redirect callback for the connect flow fails, will be one of Auth0's\n * Authentication API's Standard Error Responses: https://auth0.com/docs/api/authentication?javascript#standard-error-responses\n */\nexport class ConnectError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public connection: string,\n public state: string,\n public appState: any = null\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, ConnectError.prototype);\n }\n}\n\n/**\n * Thrown when silent auth times out (usually due to a configuration issue) or\n * when network requests to the Auth server timeout.\n */\nexport class TimeoutError extends GenericError {\n constructor() {\n super('timeout', 'Timeout');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\n/**\n * Error thrown when the login popup times out (if the user does not complete auth)\n */\nexport class PopupTimeoutError extends TimeoutError {\n constructor(public popup: Window) {\n super();\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupTimeoutError.prototype);\n }\n}\n\nexport class PopupCancelledError extends GenericError {\n constructor(public popup: Window) {\n super('cancelled', 'Popup closed');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupCancelledError.prototype);\n }\n}\n\nexport class PopupOpenError extends GenericError {\n constructor() {\n super('popup_open', 'Unable to open a popup for loginWithPopup - window.open returned `null`');\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, PopupOpenError.prototype);\n }\n}\n\n/**\n * Error thrown when the token exchange results in a `mfa_required` error\n */\nexport class MfaRequiredError extends GenericError {\n constructor(\n error: string,\n error_description: string,\n public mfa_token: string,\n public mfa_requirements: MfaRequirements\n ) {\n super(error, error_description);\n //https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, MfaRequiredError.prototype);\n }\n}\n\n/**\n * Error thrown when there is no refresh token to use\n */\nexport class MissingRefreshTokenError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_refresh_token',\n `Missing Refresh Token (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingRefreshTokenError.prototype);\n }\n}\n\n/**\n * Error thrown when there are missing scopes after refreshing a token\n */\nexport class MissingScopesError extends GenericError {\n constructor(public audience: string, public scope: string) {\n super(\n 'missing_scopes',\n `Missing requested scopes after refresh (audience: '${valueOrEmptyString(audience, [\n 'default'\n ])}', missing scope: '${valueOrEmptyString(scope)}')`\n );\n Object.setPrototypeOf(this, MissingScopesError.prototype);\n }\n}\n\n/**\n * Error thrown when the wrong DPoP nonce is used and a potential subsequent retry wasn't able to fix it.\n */\nexport class UseDpopNonceError extends GenericError {\n constructor(public newDpopNonce: string | undefined) {\n super('use_dpop_nonce', 'Server rejected DPoP proof: wrong nonce');\n\n Object.setPrototypeOf(this, UseDpopNonceError.prototype);\n }\n}\n\n/**\n * Returns an empty string when value is falsy, or when it's value is included in the exclude argument.\n * @param value The value to check\n * @param exclude An array of values that should result in an empty string.\n * @returns The value, or an empty string when falsy or included in the exclude argument.\n */\nfunction valueOrEmptyString(value: string, exclude: string[] = []) {\n return value && !exclude.includes(value) ? value : '';\n}\n","import { AuthenticationResult, PopupConfigOptions } from './global';\n\nimport {\n DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS,\n CLEANUP_IFRAME_TIMEOUT_IN_SECONDS\n} from './constants';\n\nimport {\n PopupTimeoutError,\n TimeoutError,\n GenericError,\n PopupCancelledError\n} from './errors';\n\nexport const parseAuthenticationResult = (\n queryString: string\n): AuthenticationResult => {\n if (queryString.indexOf('#') > -1) {\n queryString = queryString.substring(0, queryString.indexOf('#'));\n }\n\n const searchParams = new URLSearchParams(queryString);\n\n return {\n state: searchParams.get('state')!,\n code: searchParams.get('code') || undefined,\n connect_code: searchParams.get('connect_code') || undefined,\n error: searchParams.get('error') || undefined,\n error_description: searchParams.get('error_description') || undefined\n };\n};\n\nexport const runIframe = (\n authorizeUrl: string,\n eventOrigin: string,\n timeoutInSeconds: number = DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS\n) => {\n return new Promise<AuthenticationResult>((res, rej) => {\n const iframe = window.document.createElement('iframe');\n\n iframe.setAttribute('width', '0');\n iframe.setAttribute('height', '0');\n iframe.style.display = 'none';\n\n const removeIframe = () => {\n if (window.document.body.contains(iframe)) {\n window.document.body.removeChild(iframe);\n window.removeEventListener('message', iframeEventHandler, false);\n }\n };\n\n let iframeEventHandler: (e: MessageEvent) => void;\n\n const timeoutSetTimeoutId = setTimeout(() => {\n rej(new TimeoutError());\n removeIframe();\n }, timeoutInSeconds * 1000);\n\n iframeEventHandler = function (e: MessageEvent) {\n if (e.origin != eventOrigin) return;\n if (!e.data || e.data.type !== 'authorization_response') return;\n\n const eventSource = e.source;\n\n if (eventSource) {\n (eventSource as any).close();\n }\n\n e.data.response.error\n ? rej(GenericError.fromPayload(e.data.response))\n : res(e.data.response);\n\n clearTimeout(timeoutSetTimeoutId);\n window.removeEventListener('message', iframeEventHandler, false);\n\n // Delay the removal of the iframe to prevent hanging loading status\n // in Chrome: https://github.com/auth0/auth0-spa-js/issues/240\n setTimeout(removeIframe, CLEANUP_IFRAME_TIMEOUT_IN_SECONDS * 1000);\n };\n\n window.addEventListener('message', iframeEventHandler, false);\n window.document.body.appendChild(iframe);\n iframe.setAttribute('src', authorizeUrl);\n });\n};\n\nexport const openPopup = (url: string) => {\n const width = 400;\n const height = 600;\n const left = window.screenX + (window.innerWidth - width) / 2;\n const top = window.screenY + (window.innerHeight - height) / 2;\n\n return window.open(\n url,\n 'auth0:authorize:popup',\n `left=${left},top=${top},width=${width},height=${height},resizable,scrollbars=yes,status=1`\n );\n};\n\nexport const runPopup = (config: PopupConfigOptions) => {\n return new Promise<AuthenticationResult>((resolve, reject) => {\n let popupEventListener: (e: MessageEvent) => void;\n\n // Check each second if the popup is closed triggering a PopupCancelledError\n const popupTimer = setInterval(() => {\n if (config.popup && config.popup.closed) {\n clearInterval(popupTimer);\n clearTimeout(timeoutId);\n window.removeEventListener('message', popupEventListener, false);\n reject(new PopupCancelledError(config.popup));\n }\n }, 1000);\n\n const timeoutId = setTimeout(() => {\n clearInterval(popupTimer);\n reject(new PopupTimeoutError(config.popup));\n window.removeEventListener('message', popupEventListener, false);\n }, (config.timeoutInSeconds || DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS) * 1000);\n\n popupEventListener = function (e: MessageEvent) {\n if (!e.data || e.data.type !== 'authorization_response') {\n return;\n }\n\n clearTimeout(timeoutId);\n clearInterval(popupTimer);\n window.removeEventListener('message', popupEventListener, false);\n\n // Close popup automatically unless closePopup is explicitly set to false\n if (config.closePopup !== false) {\n config.popup.close();\n }\n\n if (e.data.response.error) {\n return reject(GenericError.fromPayload(e.data.response));\n }\n\n resolve(e.data.response);\n };\n\n window.addEventListener('message', popupEventListener);\n });\n};\n\nexport const getCrypto = () => {\n return window.crypto;\n};\n\nexport const createRandomString = () => {\n const charset =\n '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.';\n const validMax = 256 - (256 % charset.length);\n let random = '';\n while (random.length < 43) {\n const bytes = getCrypto().getRandomValues(new Uint8Array(43 - random.length));\n for (const byte of bytes) {\n if (random.length < 43 && byte < validMax) {\n random += charset[byte % charset.length];\n }\n }\n }\n return random;\n};\n\nexport const encode = (value: string) => btoa(value);\nexport const decode = (value: string) => atob(value);\n\nconst stripUndefined = (params: any) => {\n return Object.keys(params)\n .filter(k => typeof params[k] !== 'undefined')\n .reduce((acc, key) => ({ ...acc, [key]: params[key] }), {});\n};\n\nconst ALLOWED_AUTH0CLIENT_PROPERTIES = [\n {\n key: 'name',\n type: ['string']\n },\n {\n key: 'version',\n type: ['string', 'number']\n },\n {\n key: 'env',\n type: ['object']\n }\n];\n\n/**\n * Strips any property that is not present in ALLOWED_AUTH0CLIENT_PROPERTIES\n * @param auth0Client - The full auth0Client object\n * @param excludeEnv - If true, excludes the 'env' property from the result\n * @returns The stripped auth0Client object\n */\nexport const stripAuth0Client = (auth0Client: any, excludeEnv = false) => {\n return Object.keys(auth0Client).reduce((acc: any, key: string) => {\n // Exclude 'env' if requested (for /authorize query params to prevent truncation)\n if (excludeEnv && key === 'env') {\n return acc;\n }\n\n const allowedProperty = ALLOWED_AUTH0CLIENT_PROPERTIES.find(\n p => p.key === key\n );\n if (\n allowedProperty &&\n allowedProperty.type.includes(typeof auth0Client[key])\n ) {\n acc[key] = auth0Client[key];\n }\n\n return acc;\n }, {});\n};\n\nexport const createQueryParams = ({ clientId: client_id, ...params }: any) => {\n return new URLSearchParams(\n stripUndefined({ client_id, ...params })\n ).toString();\n};\n\nexport const sha256 = async (s: string) => {\n const digestOp: any = getCrypto().subtle.digest(\n { name: 'SHA-256' },\n new TextEncoder().encode(s)\n );\n\n return await digestOp;\n};\n\nconst urlEncodeB64 = (input: string) => {\n const b64Chars: { [index: string]: string } = { '+': '-', '/': '_', '=': '' };\n return input.replace(/[+/=]/g, (m: string) => b64Chars[m]);\n};\n\n// https://stackoverflow.com/questions/30106476/\nconst decodeB64 = (input: string) =>\n decodeURIComponent(\n atob(input)\n .split('')\n .map(c => {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join('')\n );\n\nexport const urlDecodeB64 = (input: string) =>\n decodeB64(input.replace(/_/g, '/').replace(/-/g, '+'));\n\nexport const bufferToBase64UrlEncoded = (input: number[] | Uint8Array) => {\n const ie11SafeInput = new Uint8Array(input);\n return urlEncodeB64(\n window.btoa(String.fromCharCode(...Array.from(ie11SafeInput)))\n );\n};\n\nexport const validateCrypto = () => {\n if (!getCrypto()) {\n throw new Error(\n 'For security reasons, `window.crypto` is required to run `auth0-spa-js`.'\n );\n }\n if (typeof getCrypto().subtle === 'undefined') {\n throw new Error(`\n auth0-spa-js must run on a secure origin. See https://github.com/auth0/auth0-spa-js/blob/main/FAQ.md#why-do-i-get-auth0-spa-js-must-run-on-a-secure-origin for more information.\n `);\n }\n};\n\n/**\n * @ignore\n */\nexport const getDomain = (domainUrl: string) => {\n if (!/^https?:\\/\\//.test(domainUrl)) {\n return `https://${domainUrl}`;\n }\n\n return domainUrl;\n};\n\n/**\n * @ignore\n */\nexport const getTokenIssuer = (\n issuer: string | undefined,\n domainUrl: string\n) => {\n if (issuer) {\n return issuer.startsWith('https://') ? issuer : `https://${issuer}/`;\n }\n\n return `${domainUrl}/`;\n};\n\nexport const parseNumber = (value: any): number | undefined => {\n if (typeof value !== 'string') {\n return value;\n }\n return parseInt(value, 10) || undefined;\n};\n\n/**\n * Ponyfill for `Object.fromEntries()`, which is not available until ES2020.\n *\n * When the target of this project reaches ES2020, this can be removed.\n */\nexport const fromEntries = <T = any>(\n iterable: Iterable<[PropertyKey, T]>\n): Record<PropertyKey, T> => {\n return [...iterable].reduce((obj, [key, val]) => {\n obj[key] = val;\n\n return obj;\n }, {} as Record<PropertyKey, T>);\n};\n","import { MissingRefreshTokenError } from '../errors';\nimport { FetchResponse } from '../global';\nimport { createQueryParams, fromEntries } from '../utils';\nimport { WorkerRefreshTokenMessage } from './worker.types';\n\nlet refreshTokens: Record<string, string> = {};\n\nconst cacheKey = (audience: string, scope: string) => `${audience}|${scope}`;\n\nconst cacheKeyContainsAudience = (audience: string, cacheKey: string) => cacheKey.startsWith(`${audience}|`);\n\nconst getRefreshToken = (audience: string, scope: string): string | undefined =>\n refreshTokens[cacheKey(audience, scope)];\n\nconst setRefreshToken = (\n refreshToken: string,\n audience: string,\n scope: string\n) => (refreshTokens[cacheKey(audience, scope)] = refreshToken);\n\nconst deleteRefreshToken = (audience: string, scope: string) =>\n delete refreshTokens[cacheKey(audience, scope)];\n\nconst wait = (time: number) =>\n new Promise<void>(resolve => setTimeout(resolve, time));\n\nconst formDataToObject = (formData: string): Record<string, any> => {\n const queryParams = new URLSearchParams(formData);\n const parsedQuery: any = {};\n\n queryParams.forEach((val, key) => {\n parsedQuery[key] = val;\n });\n\n return parsedQuery;\n};\n\nconst updateRefreshTokens = (oldRefreshToken: string | undefined, newRefreshToken: string): void => {\n Object.entries(refreshTokens).forEach(([key, token]) => {\n if (token === oldRefreshToken) {\n refreshTokens[key] = newRefreshToken;\n }\n });\n}\n\nconst checkDownscoping = (scope: string, audience: string): boolean => {\n const findCoincidence = Object.keys(refreshTokens).find((key) => {\n if (key !== 'latest_refresh_token') {\n const isSameAudience = cacheKeyContainsAudience(audience, key);\n const scopesKey = key.split('|')[1].split(\" \");\n const requestedScopes = scope.split(\" \");\n const scopesAreIncluded = requestedScopes.every((key) => scopesKey.includes(key));\n\n return isSameAudience && scopesAreIncluded;\n }\n })\n\n return findCoincidence ? true : false;\n}\n\nconst messageHandler = async ({\n data: { timeout, auth, fetchUrl, fetchOptions, useFormData, useMrrt },\n ports: [port]\n}: MessageEvent<WorkerRefreshTokenMessage>) => {\n let headers: FetchResponse['headers'] = {};\n\n let json: {\n refresh_token?: string;\n };\n let refreshToken: string | undefined;\n\n const { audience, scope } = auth || {};\n\n try {\n const body = useFormData\n ? formDataToObject(fetchOptions.body as string)\n : JSON.parse(fetchOptions.body as string);\n\n if (!body.refresh_token && body.grant_type === 'refresh_token') {\n refreshToken = getRefreshToken(audience, scope);\n\n // When we don't have any refresh_token that matches the audience and scopes\n // stored, and useMrrt is configured to true, we will use the last refresh_token\n // returned by the server to do a refresh\n // We will avoid doing MRRT if we were to downscope while doing refresh in the same audience\n if (!refreshToken && useMrrt) {\n const latestRefreshToken = refreshTokens[\"latest_refresh_token\"];\n\n const isDownscoping = checkDownscoping(scope, audience);\n\n if (latestRefreshToken && !isDownscoping) {\n refreshToken = latestRefreshToken;\n }\n }\n\n if (!refreshToken) {\n throw new MissingRefreshTokenError(audience, scope);\n }\n\n fetchOptions.body = useFormData\n ? createQueryParams({\n ...body,\n refresh_token: refreshToken\n })\n : JSON.stringify({\n ...body,\n refresh_token: refreshToken\n });\n }\n\n let abortController: AbortController | undefined;\n\n if (typeof AbortController === 'function') {\n abortController = new AbortController();\n fetchOptions.signal = abortController.signal;\n }\n\n let response: void | Response;\n\n try {\n response = await Promise.race([\n wait(timeout),\n fetch(fetchUrl, { ...fetchOptions })\n ]);\n } catch (error) {\n // fetch error, reject `sendMessage` using `error` key so that we retry.\n port.postMessage({\n error: error.message\n });\n\n return;\n }\n\n if (!response) {\n // If the request times out, abort it and let `switchFetch` raise the error.\n if (abortController) abortController.abort();\n\n port.postMessage({\n error: \"Timeout when executing 'fetch'\"\n });\n\n return;\n }\n\n headers = fromEntries(response.headers);\n json = await response.json();\n\n if (json.refresh_token) {\n // If useMrrt is configured to true we want to save the latest refresh_token\n // to be used when refreshing tokens with MRRT\n if (useMrrt) {\n refreshTokens[\"latest_refresh_token\"] = json.refresh_token;\n\n // To avoid having some refresh_token that has already been used\n // we will update those inside the list with the new one obtained\n // by the server\n updateRefreshTokens(refreshToken, json.refresh_token);\n }\n\n setRefreshToken(json.refresh_token, audience, scope);\n delete json.refresh_token;\n } else {\n deleteRefreshToken(audience, scope);\n }\n\n port.postMessage({\n ok: response.ok,\n json,\n headers\n });\n } catch (error) {\n port.postMessage({\n ok: false,\n json: {\n error: error.error,\n error_description: error.message\n },\n headers\n });\n }\n};\n\n// Don't run `addEventListener` in our tests (this is replaced in rollup)\nif (process.env.NODE_ENV === 'test') {\n module.exports = { messageHandler };\n /* c8 ignore next 4 */\n} else {\n // @ts-ignore\n addEventListener('message', messageHandler);\n}\n"],"names":["GenericError","Error","constructor","error","error_description","super","this","Object","setPrototypeOf","prototype","fromPayload","_ref","MissingRefreshTokenError","audience","scope","concat","valueOrEmptyString","value","includes","createQueryParams","_a","clientId","client_id","params","__rest","URLSearchParams","keys","filter","k","reduce","acc","key","assign","stripUndefined","toString","refreshTokens","cacheKey","addEventListener","async","json","refreshToken","data","timeout","auth","fetchUrl","fetchOptions","useFormData","useMrrt","ports","port","_ref2","headers","body","formData","queryParams","parsedQuery","forEach","val","formDataToObject","JSON","parse","refresh_token","grant_type","getRefreshToken","latestRefreshToken","isDownscoping","checkDownscoping","findCoincidence","find","isSameAudience","cacheKeyContainsAudience","startsWith","scopesKey","split","scopesAreIncluded","every","stringify","abortController","response","AbortController","signal","Promise","race","time","resolve","setTimeout","fetch","postMessage","message","abort","iterable","obj","oldRefreshToken","newRefreshToken","entries","token","setRefreshToken","deleteRefreshToken","ok","updateRefreshTokens"],"mappings":"0FAaM,MAAOA,UAAqBC,MAChCC,WAAAA,CAAmBC,EAAsBC,GACvCC,MAAMD,GADWE,KAAKH,MAALA,EAAsBG,KAAiBF,kBAAjBA,EAEvCG,OAAOC,eAAeF,KAAMN,EAAaS,UAC3C,CAEA,kBAAOC,CAAWC,GAMjB,IANkBR,MACjBA,EAAKC,kBACLA,GAIDO,EACC,OAAO,IAAIX,EAAaG,EAAOC,EACjC,EAgGI,MAAOQ,UAAiCZ,EAC5CE,WAAAA,CAAmBW,EAAyBC,GAC1CT,MACE,wBAAuBU,qCAAAA,OACcC,EAAmBH,EAAU,CAChE,2BACAE,OAAcC,EAAmBF,GAAM,OAL1BR,KAAQO,SAARA,EAAyBP,KAAKQ,MAALA,EAO1CP,OAAOC,eAAeF,KAAMM,EAAyBH,UACvD,EAmCF,SAASO,EAAmBC,GAC1B,OAAOA,4DADsD,IACpCC,SAASD,GAASA,EAAQ,EACrD,qDCFA,MAgDaE,EAAqBC,QAAEC,SAAUC,GAASF,EAAKG,2UAAMC,CAAAJ,EAAhC,cAChC,OAAO,IAAIK,gBAjDWF,IACfhB,OAAOmB,KAAKH,GAChBI,OAAOC,QAA0B,IAAdL,EAAOK,IAC1BC,OAAO,CAACC,EAAKC,IAAQxB,OAAAyB,OAAAzB,OAAAyB,OAAA,GAAMF,GAAG,CAAEC,CAACA,GAAMR,EAAOQ,KAAS,CAAE,GA+C1DE,CAAiB1B,OAAAyB,OAAA,CAAAV,aAAcC,KAC/BW,YCrNJ,IAAIC,EAAwC,CAAA,EAE5C,MAAMC,EAAWA,CAACvB,EAAkBC,IAAa,GAAAC,OAAQF,EAAQ,KAAAE,OAAID,GAqLnEuB,iBAAiB,UAhIIC,UAGuB,IAGxCC,EAGAC,GARJC,MAAMC,QAAEA,EAAOC,KAAEA,EAAIC,SAAEA,EAAQC,aAAEA,EAAYC,YAAEA,EAAWC,QAAEA,GAC5DC,OAAQC,IACgCC,EACpCC,EAAoC,CAAA,EAOxC,MAAMtC,SAAEA,EAAQC,MAAEA,GAAU6B,GAAQ,CAAA,EAEpC,IACE,MAAMS,EAAON,EAhDSO,KACxB,MAAMC,EAAc,IAAI7B,gBAAgB4B,GAClCE,EAAmB,CAAA,EAMzB,OAJAD,EAAYE,QAAQ,CAACC,EAAK1B,KACxBwB,EAAYxB,GAAO0B,IAGdF,GAyCDG,CAAiBb,EAAaO,MAC9BO,KAAKC,MAAMf,EAAaO,MAE5B,IAAKA,EAAKS,eAAqC,kBAApBT,EAAKU,WAAgC,CAO9D,GANAtB,EApEkBuB,EAAClD,EAAkBC,IACzCqB,EAAcC,EAASvB,EAAUC,IAmEdiD,CAAgBlD,EAAUC,IAMpC0B,GAAgBO,EAAS,CAC5B,MAAMiB,EAAqB7B,EAAoC,qBAEzD8B,EA3CWC,EAACpD,EAAeD,KACvC,MAAMsD,EAAkB5D,OAAOmB,KAAKS,GAAeiC,KAAMrC,IACvD,GAAY,yBAARA,EAAgC,CAClC,MAAMsC,EAvCqBC,EAACzD,EAAkBuB,IAAqBA,EAASmC,WAAUxD,GAAAA,OAAIF,QAuCnEyD,CAAyBzD,EAAUkB,GACpDyC,EAAYzC,EAAI0C,MAAM,KAAK,GAAGA,MAAM,KAEpCC,EADkB5D,EAAM2D,MAAM,KACME,MAAO5C,GAAQyC,EAAUtD,SAASa,IAE5E,OAAOsC,GAAkBK,CAC1B,IAGH,QAAOP,GA+BqBD,CAAiBpD,EAAOD,GAE1CmD,IAAuBC,IACzBzB,EAAewB,EAElB,CAED,IAAKxB,EACH,MAAM,IAAI5B,EAAyBC,EAAUC,GAG/C+B,EAAaO,KAAON,EAChB3B,EACGZ,OAAAyB,OAAAzB,OAAAyB,OAAA,GAAAoB,IACHS,cAAerB,KAEfmB,KAAKiB,UAASrE,OAAAyB,OAAAzB,OAAAyB,OAAA,GACXoB,GAAI,CACPS,cAAerB,IAEpB,CAED,IAAIqC,EAOAC,EAL2B,mBAApBC,kBACTF,EAAkB,IAAIE,gBACtBlC,EAAamC,OAASH,EAAgBG,QAKxC,IACEF,QAAiBG,QAAQC,KAAK,EAjGtBC,EAkGDzC,EAjGX,IAAIuC,QAAcG,GAAWC,WAAWD,EAASD,KAkG3CG,MAAM1C,EAAerC,OAAAyB,OAAA,CAAA,EAAAa,KAExB,CAAC,MAAO1C,GAMP,YAJA8C,EAAKsC,YAAY,CACfpF,MAAOA,EAAMqF,SAIhB,CAED,IAAKV,EAQH,OANID,GAAiBA,EAAgBY,aAErCxC,EAAKsC,YAAY,CACfpF,MAAO,mCDyKbuF,ECnKwBZ,EAAS3B,QAA/BA,EDqKK,IAAIuC,GAAU7D,OAAO,CAAC8D,EAAGhF,KAAgB,IAAboB,EAAK0B,GAAI9C,EAG1C,OAFAgF,EAAI5D,GAAO0B,EAEJkC,GACN,CAA4B,GCxK7BpD,QAAauC,EAASvC,OAElBA,EAAKsB,eAGHd,IACFZ,EAAoC,qBAAII,EAAKsB,cAlHxB+B,EAuHDpD,EAvHsCqD,EAuHxBtD,EAAKsB,cAtH7CtD,OAAOuF,QAAQ3D,GAAeqB,QAAQ7C,IAAiB,IAAfoB,EAAKgE,GAAMpF,EAC7CoF,IAAUH,IACZzD,EAAcJ,GAAO8D,MA1BHG,EACtBxD,EACA3B,EACAC,KACIqB,EAAcC,EAASvB,EAAUC,IAAU0B,GA6I3CwD,CAAgBzD,EAAKsB,cAAehD,EAAUC,UACvCyB,EAAKsB,eA5ISoC,EAACpF,EAAkBC,YACrCqB,EAAcC,EAASvB,EAAUC,KA6IpCmF,CAAmBpF,EAAUC,GAG/BmC,EAAKsC,YAAY,CACfW,GAAIpB,EAASoB,GACb3D,OACAY,WAEH,CAAC,MAAOhD,GACP8C,EAAKsC,YAAY,CACfW,IAAI,EACJ3D,KAAM,CACJpC,MAAOA,EAAMA,MACbC,kBAAmBD,EAAMqF,SAE3BrC,WAEH,CA9IyBgD,IAACP,EAAqCC,ED8QhEH,EC5RYP"}
@@ -18,7 +18,7 @@ typeof SuppressedError === "function" ? SuppressedError : function(error, suppre
18
18
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
19
19
  };
20
20
 
21
- var version = "2.17.1";
21
+ var version = "2.18.0";
22
22
 
23
23
  const DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS = 60;
24
24
 
@@ -254,9 +254,16 @@ const getCrypto = () => window.crypto;
254
254
 
255
255
  const createRandomString = () => {
256
256
  const charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.";
257
+ const validMax = 256 - 256 % charset.length;
257
258
  let random = "";
258
- const randomValues = Array.from(getCrypto().getRandomValues(new Uint8Array(43)));
259
- randomValues.forEach(v => random += charset[v % charset.length]);
259
+ while (random.length < 43) {
260
+ const bytes = getCrypto().getRandomValues(new Uint8Array(43 - random.length));
261
+ for (const byte of bytes) {
262
+ if (random.length < 43 && byte < validMax) {
263
+ random += charset[byte % charset.length];
264
+ }
265
+ }
266
+ }
260
267
  return random;
261
268
  };
262
269
 
@@ -2689,55 +2696,40 @@ function _wrapAsyncGenerator(e) {
2689
2696
  }
2690
2697
 
2691
2698
  function AsyncGenerator(e) {
2692
- var r, t;
2693
- function resume(r, t) {
2699
+ var t, n;
2700
+ function resume(t, n) {
2694
2701
  try {
2695
- var n = e[r](t), o = n.value, u = o instanceof _OverloadYield;
2696
- Promise.resolve(u ? o.v : o).then(function(t) {
2702
+ var r = e[t](n), o = r.value, u = o instanceof _OverloadYield;
2703
+ Promise.resolve(u ? o.v : o).then(function(n) {
2697
2704
  if (u) {
2698
- var i = "return" === r ? "return" : "next";
2699
- if (!o.k || t.done) return resume(i, t);
2700
- t = e[i](t).value;
2705
+ var i = "return" === t && o.k ? t : "next";
2706
+ if (!o.k || n.done) return resume(i, n);
2707
+ n = e[i](n).value;
2701
2708
  }
2702
- settle(n.done ? "return" : "normal", t);
2709
+ settle(!!r.done, n);
2703
2710
  }, function(e) {
2704
2711
  resume("throw", e);
2705
2712
  });
2706
2713
  } catch (e) {
2707
- settle("throw", e);
2714
+ settle(2, e);
2708
2715
  }
2709
2716
  }
2710
- function settle(e, n) {
2711
- switch (e) {
2712
- case "return":
2713
- r.resolve({
2714
- value: n,
2715
- done: !0
2716
- });
2717
- break;
2718
-
2719
- case "throw":
2720
- r.reject(n);
2721
- break;
2722
-
2723
- default:
2724
- r.resolve({
2725
- value: n,
2726
- done: !1
2727
- });
2728
- }
2729
- (r = r.next) ? resume(r.key, r.arg) : t = null;
2717
+ function settle(e, r) {
2718
+ 2 === e ? t.reject(r) : t.resolve({
2719
+ value: r,
2720
+ done: e
2721
+ }), (t = t.next) ? resume(t.key, t.arg) : n = null;
2730
2722
  }
2731
- this._invoke = function(e, n) {
2723
+ this._invoke = function(e, r) {
2732
2724
  return new Promise(function(o, u) {
2733
2725
  var i = {
2734
2726
  key: e,
2735
- arg: n,
2727
+ arg: r,
2736
2728
  resolve: o,
2737
2729
  reject: u,
2738
2730
  next: null
2739
2731
  };
2740
- t ? t = t.next = i : (r = t = i, resume(e, n));
2732
+ n ? n = n.next = i : (t = n = i, resume(e, r));
2741
2733
  });
2742
2734
  }, "function" != typeof e.return && (this.return = void 0);
2743
2735
  }
@@ -6848,7 +6840,7 @@ let USER_AGENT;
6848
6840
 
6849
6841
  if (typeof navigator === "undefined" || !((_navigator$userAgent = navigator.userAgent) !== null && _navigator$userAgent !== void 0 && (_navigator$userAgent$ = _navigator$userAgent.startsWith) !== null && _navigator$userAgent$ !== void 0 && _navigator$userAgent$.call(_navigator$userAgent, "Mozilla/5.0 "))) {
6850
6842
  const NAME = "jose";
6851
- const VERSION = "v6.2.1";
6843
+ const VERSION = "v6.2.2";
6852
6844
  USER_AGENT = "".concat(NAME, "/").concat(VERSION);
6853
6845
  }
6854
6846
 
@@ -8292,6 +8284,31 @@ class Auth0Client {
8292
8284
  });
8293
8285
  }
8294
8286
  }
8287
+ _extractSessionTransferToken(paramName) {
8288
+ const params = new URLSearchParams(window.location.search);
8289
+ return params.get(paramName) || undefined;
8290
+ }
8291
+ _clearSessionTransferTokenFromUrl(paramName) {
8292
+ try {
8293
+ const url = new URL(window.location.href);
8294
+ if (url.searchParams.has(paramName)) {
8295
+ url.searchParams.delete(paramName);
8296
+ window.history.replaceState({}, "", url.toString());
8297
+ }
8298
+ } catch (_a) {}
8299
+ }
8300
+ _applySessionTransferToken(authorizationParams) {
8301
+ const paramName = this.options.sessionTransferTokenQueryParamName;
8302
+ if (!paramName || authorizationParams.session_transfer_token) {
8303
+ return authorizationParams;
8304
+ }
8305
+ const token = this._extractSessionTransferToken(paramName);
8306
+ if (!token) return authorizationParams;
8307
+ this._clearSessionTransferTokenFromUrl(paramName);
8308
+ return Object.assign(Object.assign({}, authorizationParams), {
8309
+ session_transfer_token: token
8310
+ });
8311
+ }
8295
8312
  async _prepareAuthorizeUrl(authorizationParams, authorizeOptions, fallbackRedirectUri) {
8296
8313
  var _a;
8297
8314
  const state = encode$2(createRandomString());
@@ -8322,7 +8339,8 @@ class Auth0Client {
8322
8339
  throw new PopupOpenError;
8323
8340
  }
8324
8341
  }
8325
- const params = await this._prepareAuthorizeUrl(options.authorizationParams || {}, {
8342
+ const authorizationParams = this._applySessionTransferToken(options.authorizationParams || {});
8343
+ const params = await this._prepareAuthorizeUrl(authorizationParams, {
8326
8344
  response_mode: "web_message"
8327
8345
  }, window.location.origin);
8328
8346
  config.popup.location.href = params.url;
@@ -8360,7 +8378,8 @@ class Auth0Client {
8360
8378
  var _a;
8361
8379
  const _b = patchOpenUrlWithOnRedirect(options), {openUrl: openUrl, fragment: fragment, appState: appState} = _b, urlOptions = __rest(_b, [ "openUrl", "fragment", "appState" ]);
8362
8380
  const organization = ((_a = urlOptions.authorizationParams) === null || _a === void 0 ? void 0 : _a.organization) || this.options.authorizationParams.organization;
8363
- const _c = await this._prepareAuthorizeUrl(urlOptions.authorizationParams || {}), {url: url} = _c, transaction = __rest(_c, [ "url" ]);
8381
+ const authorizationParams = this._applySessionTransferToken(urlOptions.authorizationParams || {});
8382
+ const _c = await this._prepareAuthorizeUrl(authorizationParams), {url: url} = _c, transaction = __rest(_c, [ "url" ]);
8364
8383
  this.transactionManager.create(Object.assign(Object.assign(Object.assign({}, transaction), {
8365
8384
  appState: appState,
8366
8385
  response_type: exports.ResponseType.Code