UNPKG

@auth0/auth0-spa-js

Version:

Auth0 SDK for Single Page Applications using Authorization Code Grant Flow with PKCE

1,417 lines (1,279 loc) 131 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {}; function unwrapExports(x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x; } function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var processLock = createCommonjsModule((function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); var ProcessLocking = function() { function ProcessLocking() { var _this = this; this.locked = new Map; this.addToLocked = function(key, toAdd) { var callbacks = _this.locked.get(key); if (callbacks === undefined) { if (toAdd === undefined) { _this.locked.set(key, []); } else { _this.locked.set(key, [ toAdd ]); } } else { if (toAdd !== undefined) { callbacks.unshift(toAdd); _this.locked.set(key, callbacks); } } }; this.isLocked = function(key) { return _this.locked.has(key); }; this.lock = function(key) { return new Promise((function(resolve, reject) { if (_this.isLocked(key)) { _this.addToLocked(key, resolve); } else { _this.addToLocked(key); resolve(); } })); }; this.unlock = function(key) { var callbacks = _this.locked.get(key); if (callbacks === undefined || callbacks.length === 0) { _this.locked.delete(key); return; } var toCall = callbacks.pop(); _this.locked.set(key, callbacks); if (toCall !== undefined) { setTimeout(toCall, 0); } }; } ProcessLocking.getInstance = function() { if (ProcessLocking.instance === undefined) { ProcessLocking.instance = new ProcessLocking; } return ProcessLocking.instance; }; return ProcessLocking; }(); function getLock() { return ProcessLocking.getInstance(); } exports.default = getLock; })); unwrapExports(processLock); var browserTabsLock = createCommonjsModule((function(module, exports) { var __awaiter = commonjsGlobal && commonjsGlobal.__awaiter || function(thisArg, _arguments, P, generator) { return new (P || (P = Promise))((function(resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P((function(resolve) { resolve(result.value); })).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); })); }; var __generator = commonjsGlobal && commonjsGlobal.__generator || function(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), throw: verb(1), return: verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function(v) { return step([ n, v ]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [ op[0] & 2, t.value ]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [ 0 ]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [ 6, e ]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var _this = commonjsGlobal; Object.defineProperty(exports, "__esModule", { value: true }); var LOCK_STORAGE_KEY = "browser-tabs-lock-key"; var DEFAULT_STORAGE_HANDLER = { key: function(index) { return __awaiter(_this, void 0, void 0, (function() { return __generator(this, (function(_a) { throw new Error("Unsupported"); })); })); }, getItem: function(key) { return __awaiter(_this, void 0, void 0, (function() { return __generator(this, (function(_a) { throw new Error("Unsupported"); })); })); }, clear: function() { return __awaiter(_this, void 0, void 0, (function() { return __generator(this, (function(_a) { return [ 2, window.localStorage.clear() ]; })); })); }, removeItem: function(key) { return __awaiter(_this, void 0, void 0, (function() { return __generator(this, (function(_a) { throw new Error("Unsupported"); })); })); }, setItem: function(key, value) { return __awaiter(_this, void 0, void 0, (function() { return __generator(this, (function(_a) { throw new Error("Unsupported"); })); })); }, keySync: function(index) { return window.localStorage.key(index); }, getItemSync: function(key) { return window.localStorage.getItem(key); }, clearSync: function() { return window.localStorage.clear(); }, removeItemSync: function(key) { return window.localStorage.removeItem(key); }, setItemSync: function(key, value) { return window.localStorage.setItem(key, value); } }; function delay(milliseconds) { return new Promise((function(resolve) { return setTimeout(resolve, milliseconds); })); } function generateRandomString(length) { var CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; var randomstring = ""; for (var i = 0; i < length; i++) { var INDEX = Math.floor(Math.random() * CHARS.length); randomstring += CHARS[INDEX]; } return randomstring; } function getLockId() { return Date.now().toString() + generateRandomString(15); } var SuperTokensLock = function() { function SuperTokensLock(storageHandler) { this.acquiredIatSet = new Set; this.storageHandler = undefined; this.id = getLockId(); this.acquireLock = this.acquireLock.bind(this); this.releaseLock = this.releaseLock.bind(this); this.releaseLock__private__ = this.releaseLock__private__.bind(this); this.waitForSomethingToChange = this.waitForSomethingToChange.bind(this); this.refreshLockWhileAcquired = this.refreshLockWhileAcquired.bind(this); this.storageHandler = storageHandler; if (SuperTokensLock.waiters === undefined) { SuperTokensLock.waiters = []; } } SuperTokensLock.prototype.acquireLock = function(lockKey, timeout) { if (timeout === void 0) { timeout = 5e3; } return __awaiter(this, void 0, void 0, (function() { var iat, MAX_TIME, STORAGE_KEY, STORAGE, lockObj, TIMEOUT_KEY, lockObjPostDelay, parsedLockObjPostDelay; return __generator(this, (function(_a) { switch (_a.label) { case 0: iat = Date.now() + generateRandomString(4); MAX_TIME = Date.now() + timeout; STORAGE_KEY = LOCK_STORAGE_KEY + "-" + lockKey; STORAGE = this.storageHandler === undefined ? DEFAULT_STORAGE_HANDLER : this.storageHandler; _a.label = 1; case 1: if (!(Date.now() < MAX_TIME)) return [ 3, 8 ]; return [ 4, delay(30) ]; case 2: _a.sent(); lockObj = STORAGE.getItemSync(STORAGE_KEY); if (!(lockObj === null)) return [ 3, 5 ]; TIMEOUT_KEY = this.id + "-" + lockKey + "-" + iat; return [ 4, delay(Math.floor(Math.random() * 25)) ]; case 3: _a.sent(); STORAGE.setItemSync(STORAGE_KEY, JSON.stringify({ id: this.id, iat: iat, timeoutKey: TIMEOUT_KEY, timeAcquired: Date.now(), timeRefreshed: Date.now() })); return [ 4, delay(30) ]; case 4: _a.sent(); lockObjPostDelay = STORAGE.getItemSync(STORAGE_KEY); if (lockObjPostDelay !== null) { parsedLockObjPostDelay = JSON.parse(lockObjPostDelay); if (parsedLockObjPostDelay.id === this.id && parsedLockObjPostDelay.iat === iat) { this.acquiredIatSet.add(iat); this.refreshLockWhileAcquired(STORAGE_KEY, iat); return [ 2, true ]; } } return [ 3, 7 ]; case 5: SuperTokensLock.lockCorrector(this.storageHandler === undefined ? DEFAULT_STORAGE_HANDLER : this.storageHandler); return [ 4, this.waitForSomethingToChange(MAX_TIME) ]; case 6: _a.sent(); _a.label = 7; case 7: iat = Date.now() + generateRandomString(4); return [ 3, 1 ]; case 8: return [ 2, false ]; } })); })); }; SuperTokensLock.prototype.refreshLockWhileAcquired = function(storageKey, iat) { return __awaiter(this, void 0, void 0, (function() { var _this = this; return __generator(this, (function(_a) { setTimeout((function() { return __awaiter(_this, void 0, void 0, (function() { var STORAGE, lockObj, parsedLockObj; return __generator(this, (function(_a) { switch (_a.label) { case 0: return [ 4, processLock.default().lock(iat) ]; case 1: _a.sent(); if (!this.acquiredIatSet.has(iat)) { processLock.default().unlock(iat); return [ 2 ]; } STORAGE = this.storageHandler === undefined ? DEFAULT_STORAGE_HANDLER : this.storageHandler; lockObj = STORAGE.getItemSync(storageKey); if (lockObj !== null) { parsedLockObj = JSON.parse(lockObj); parsedLockObj.timeRefreshed = Date.now(); STORAGE.setItemSync(storageKey, JSON.stringify(parsedLockObj)); processLock.default().unlock(iat); } else { processLock.default().unlock(iat); return [ 2 ]; } this.refreshLockWhileAcquired(storageKey, iat); return [ 2 ]; } })); })); }), 1e3); return [ 2 ]; })); })); }; SuperTokensLock.prototype.waitForSomethingToChange = function(MAX_TIME) { return __awaiter(this, void 0, void 0, (function() { return __generator(this, (function(_a) { switch (_a.label) { case 0: return [ 4, new Promise((function(resolve) { var resolvedCalled = false; var startedAt = Date.now(); var MIN_TIME_TO_WAIT = 50; var removedListeners = false; function stopWaiting() { if (!removedListeners) { window.removeEventListener("storage", stopWaiting); SuperTokensLock.removeFromWaiting(stopWaiting); clearTimeout(timeOutId); removedListeners = true; } if (!resolvedCalled) { resolvedCalled = true; var timeToWait = MIN_TIME_TO_WAIT - (Date.now() - startedAt); if (timeToWait > 0) { setTimeout(resolve, timeToWait); } else { resolve(null); } } } window.addEventListener("storage", stopWaiting); SuperTokensLock.addToWaiting(stopWaiting); var timeOutId = setTimeout(stopWaiting, Math.max(0, MAX_TIME - Date.now())); })) ]; case 1: _a.sent(); return [ 2 ]; } })); })); }; SuperTokensLock.addToWaiting = function(func) { this.removeFromWaiting(func); if (SuperTokensLock.waiters === undefined) { return; } SuperTokensLock.waiters.push(func); }; SuperTokensLock.removeFromWaiting = function(func) { if (SuperTokensLock.waiters === undefined) { return; } SuperTokensLock.waiters = SuperTokensLock.waiters.filter((function(i) { return i !== func; })); }; SuperTokensLock.notifyWaiters = function() { if (SuperTokensLock.waiters === undefined) { return; } var waiters = SuperTokensLock.waiters.slice(); waiters.forEach((function(i) { return i(); })); }; SuperTokensLock.prototype.releaseLock = function(lockKey) { return __awaiter(this, void 0, void 0, (function() { return __generator(this, (function(_a) { switch (_a.label) { case 0: return [ 4, this.releaseLock__private__(lockKey) ]; case 1: return [ 2, _a.sent() ]; } })); })); }; SuperTokensLock.prototype.releaseLock__private__ = function(lockKey) { return __awaiter(this, void 0, void 0, (function() { var STORAGE, STORAGE_KEY, lockObj, parsedlockObj; return __generator(this, (function(_a) { switch (_a.label) { case 0: STORAGE = this.storageHandler === undefined ? DEFAULT_STORAGE_HANDLER : this.storageHandler; STORAGE_KEY = LOCK_STORAGE_KEY + "-" + lockKey; lockObj = STORAGE.getItemSync(STORAGE_KEY); if (lockObj === null) { return [ 2 ]; } parsedlockObj = JSON.parse(lockObj); if (!(parsedlockObj.id === this.id)) return [ 3, 2 ]; return [ 4, processLock.default().lock(parsedlockObj.iat) ]; case 1: _a.sent(); this.acquiredIatSet.delete(parsedlockObj.iat); STORAGE.removeItemSync(STORAGE_KEY); processLock.default().unlock(parsedlockObj.iat); SuperTokensLock.notifyWaiters(); _a.label = 2; case 2: return [ 2 ]; } })); })); }; SuperTokensLock.lockCorrector = function(storageHandler) { var MIN_ALLOWED_TIME = Date.now() - 5e3; var STORAGE = storageHandler; var KEYS = []; var currIndex = 0; while (true) { var key = STORAGE.keySync(currIndex); if (key === null) { break; } KEYS.push(key); currIndex++; } var notifyWaiters = false; for (var i = 0; i < KEYS.length; i++) { var LOCK_KEY = KEYS[i]; if (LOCK_KEY.includes(LOCK_STORAGE_KEY)) { var lockObj = STORAGE.getItemSync(LOCK_KEY); if (lockObj !== null) { var parsedlockObj = JSON.parse(lockObj); if (parsedlockObj.timeRefreshed === undefined && parsedlockObj.timeAcquired < MIN_ALLOWED_TIME || parsedlockObj.timeRefreshed !== undefined && parsedlockObj.timeRefreshed < MIN_ALLOWED_TIME) { STORAGE.removeItemSync(LOCK_KEY); notifyWaiters = true; } } } } if (notifyWaiters) { SuperTokensLock.notifyWaiters(); } }; SuperTokensLock.waiters = undefined; return SuperTokensLock; }(); exports.default = SuperTokensLock; })); var Lock = unwrapExports(browserTabsLock); var version = "2.10.0"; const DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS = 60; const DEFAULT_POPUP_CONFIG_OPTIONS = { timeoutInSeconds: DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS }; const DEFAULT_SILENT_TOKEN_RETRY_COUNT = 3; const CLEANUP_IFRAME_TIMEOUT_IN_SECONDS = 2; const DEFAULT_FETCH_TIMEOUT_MS = 1e4; const CACHE_LOCATION_MEMORY = "memory"; const MISSING_REFRESH_TOKEN_ERROR_MESSAGE = "Missing Refresh Token"; const INVALID_REFRESH_TOKEN_ERROR_MESSAGE = "invalid refresh token"; const DEFAULT_SCOPE = "openid profile email"; const DEFAULT_SESSION_CHECK_EXPIRY_DAYS = 1; const DEFAULT_AUTH0_CLIENT = { name: "auth0-spa-js", version: version }; const DEFAULT_NOW_PROVIDER = () => Date.now(); const DEFAULT_AUDIENCE = "default"; class GenericError extends Error { constructor(error, error_description) { super(error_description); this.error = error; this.error_description = error_description; Object.setPrototypeOf(this, GenericError.prototype); } static fromPayload({error: error, error_description: error_description}) { return new GenericError(error, error_description); } } class AuthenticationError extends GenericError { constructor(error, error_description, state, appState = null) { super(error, error_description); this.state = state; this.appState = appState; Object.setPrototypeOf(this, AuthenticationError.prototype); } } class ConnectError extends GenericError { constructor(error, error_description, connection, state, appState = null) { super(error, error_description); this.connection = connection; this.state = state; this.appState = appState; Object.setPrototypeOf(this, ConnectError.prototype); } } class TimeoutError extends GenericError { constructor() { super("timeout", "Timeout"); Object.setPrototypeOf(this, TimeoutError.prototype); } } class PopupTimeoutError extends TimeoutError { constructor(popup) { super(); this.popup = popup; Object.setPrototypeOf(this, PopupTimeoutError.prototype); } } class PopupCancelledError extends GenericError { constructor(popup) { super("cancelled", "Popup closed"); this.popup = popup; Object.setPrototypeOf(this, PopupCancelledError.prototype); } } class PopupOpenError extends GenericError { constructor() { super("popup_open", "Unable to open a popup for loginWithPopup - window.open returned `null`"); Object.setPrototypeOf(this, PopupOpenError.prototype); } } class MfaRequiredError extends GenericError { constructor(error, error_description, mfa_token) { super(error, error_description); this.mfa_token = mfa_token; Object.setPrototypeOf(this, MfaRequiredError.prototype); } } class MissingRefreshTokenError extends GenericError { constructor(audience, scope) { super("missing_refresh_token", `Missing Refresh Token (audience: '${valueOrEmptyString(audience, [ "default" ])}', scope: '${valueOrEmptyString(scope)}')`); this.audience = audience; this.scope = scope; Object.setPrototypeOf(this, MissingRefreshTokenError.prototype); } } class MissingScopesError extends GenericError { constructor(audience, scope) { super("missing_scopes", `Missing requested scopes after refresh (audience: '${valueOrEmptyString(audience, [ "default" ])}', missing scope: '${valueOrEmptyString(scope)}')`); this.audience = audience; this.scope = scope; Object.setPrototypeOf(this, MissingScopesError.prototype); } } class UseDpopNonceError extends GenericError { constructor(newDpopNonce) { super("use_dpop_nonce", "Server rejected DPoP proof: wrong nonce"); this.newDpopNonce = newDpopNonce; Object.setPrototypeOf(this, UseDpopNonceError.prototype); } } function valueOrEmptyString(value, exclude = []) { return value && !exclude.includes(value) ? value : ""; } const parseAuthenticationResult = queryString => { if (queryString.indexOf("#") > -1) { queryString = queryString.substring(0, queryString.indexOf("#")); } const searchParams = new URLSearchParams(queryString); return { state: searchParams.get("state"), code: searchParams.get("code") || undefined, connect_code: searchParams.get("connect_code") || undefined, error: searchParams.get("error") || undefined, error_description: searchParams.get("error_description") || undefined }; }; const runIframe = (authorizeUrl, eventOrigin, timeoutInSeconds = DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS) => new Promise(((res, rej) => { const iframe = window.document.createElement("iframe"); iframe.setAttribute("width", "0"); iframe.setAttribute("height", "0"); iframe.style.display = "none"; const removeIframe = () => { if (window.document.body.contains(iframe)) { window.document.body.removeChild(iframe); window.removeEventListener("message", iframeEventHandler, false); } }; let iframeEventHandler; const timeoutSetTimeoutId = setTimeout((() => { rej(new TimeoutError); removeIframe(); }), timeoutInSeconds * 1e3); iframeEventHandler = function(e) { if (e.origin != eventOrigin) return; if (!e.data || e.data.type !== "authorization_response") return; const eventSource = e.source; if (eventSource) { eventSource.close(); } e.data.response.error ? rej(GenericError.fromPayload(e.data.response)) : res(e.data.response); clearTimeout(timeoutSetTimeoutId); window.removeEventListener("message", iframeEventHandler, false); setTimeout(removeIframe, CLEANUP_IFRAME_TIMEOUT_IN_SECONDS * 1e3); }; window.addEventListener("message", iframeEventHandler, false); window.document.body.appendChild(iframe); iframe.setAttribute("src", authorizeUrl); })); const openPopup = url => { const width = 400; const height = 600; const left = window.screenX + (window.innerWidth - width) / 2; const top = window.screenY + (window.innerHeight - height) / 2; return window.open(url, "auth0:authorize:popup", `left=${left},top=${top},width=${width},height=${height},resizable,scrollbars=yes,status=1`); }; const runPopup = config => new Promise(((resolve, reject) => { let popupEventListener; const popupTimer = setInterval((() => { if (config.popup && config.popup.closed) { clearInterval(popupTimer); clearTimeout(timeoutId); window.removeEventListener("message", popupEventListener, false); reject(new PopupCancelledError(config.popup)); } }), 1e3); const timeoutId = setTimeout((() => { clearInterval(popupTimer); reject(new PopupTimeoutError(config.popup)); window.removeEventListener("message", popupEventListener, false); }), (config.timeoutInSeconds || DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS) * 1e3); popupEventListener = function(e) { if (!e.data || e.data.type !== "authorization_response") { return; } clearTimeout(timeoutId); clearInterval(popupTimer); window.removeEventListener("message", popupEventListener, false); config.popup.close(); if (e.data.response.error) { return reject(GenericError.fromPayload(e.data.response)); } resolve(e.data.response); }; window.addEventListener("message", popupEventListener); })); const getCrypto = () => window.crypto; const createRandomString = () => { const charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~."; let random = ""; const randomValues = Array.from(getCrypto().getRandomValues(new Uint8Array(43))); randomValues.forEach((v => random += charset[v % charset.length])); return random; }; const encode = value => btoa(value); const stripUndefined = params => Object.keys(params).filter((k => typeof params[k] !== "undefined")).reduce(((acc, key) => Object.assign(Object.assign({}, acc), { [key]: params[key] })), {}); const ALLOWED_AUTH0CLIENT_PROPERTIES = [ { key: "name", type: [ "string" ] }, { key: "version", type: [ "string", "number" ] }, { key: "env", type: [ "object" ] } ]; const stripAuth0Client = auth0Client => Object.keys(auth0Client).reduce(((acc, key) => { const allowedProperty = ALLOWED_AUTH0CLIENT_PROPERTIES.find((p => p.key === key)); if (allowedProperty && allowedProperty.type.includes(typeof auth0Client[key])) { acc[key] = auth0Client[key]; } return acc; }), {}); const createQueryParams = _a => { var {clientId: client_id} = _a, params = __rest(_a, [ "clientId" ]); return new URLSearchParams(stripUndefined(Object.assign({ client_id: client_id }, params))).toString(); }; const sha256 = async s => { const digestOp = getCrypto().subtle.digest({ name: "SHA-256" }, (new TextEncoder).encode(s)); return await digestOp; }; const urlEncodeB64 = input => { const b64Chars = { "+": "-", "/": "_", "=": "" }; return input.replace(/[+/=]/g, (m => b64Chars[m])); }; const decodeB64 = input => decodeURIComponent(atob(input).split("").map((c => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2))).join("")); const urlDecodeB64 = input => decodeB64(input.replace(/_/g, "/").replace(/-/g, "+")); const bufferToBase64UrlEncoded = input => { const ie11SafeInput = new Uint8Array(input); return urlEncodeB64(window.btoa(String.fromCharCode(...Array.from(ie11SafeInput)))); }; const validateCrypto = () => { if (!getCrypto()) { throw new Error("For security reasons, `window.crypto` is required to run `auth0-spa-js`."); } if (typeof getCrypto().subtle === "undefined") { 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 `); } }; const getDomain = domainUrl => { if (!/^https?:\/\//.test(domainUrl)) { return `https://${domainUrl}`; } return domainUrl; }; const getTokenIssuer = (issuer, domainUrl) => { if (issuer) { return issuer.startsWith("https://") ? issuer : `https://${issuer}/`; } return `${domainUrl}/`; }; const parseNumber = value => { if (typeof value !== "string") { return value; } return parseInt(value, 10) || undefined; }; const fromEntries = iterable => [ ...iterable ].reduce(((obj, [key, val]) => { obj[key] = val; return obj; }), {}); const encoder = new TextEncoder; const decoder = new TextDecoder; function buf(input) { if (typeof input === "string") { return encoder.encode(input); } return decoder.decode(input); } function checkRsaKeyAlgorithm(algorithm) { if (typeof algorithm.modulusLength !== "number" || algorithm.modulusLength < 2048) { throw new OperationProcessingError(`${algorithm.name} modulusLength must be at least 2048 bits`); } } function subtleAlgorithm(key) { switch (key.algorithm.name) { case "ECDSA": return { name: key.algorithm.name, hash: "SHA-256" }; case "RSA-PSS": checkRsaKeyAlgorithm(key.algorithm); return { name: key.algorithm.name, saltLength: 256 >> 3 }; case "RSASSA-PKCS1-v1_5": checkRsaKeyAlgorithm(key.algorithm); return { name: key.algorithm.name }; case "Ed25519": return { name: key.algorithm.name }; } throw new UnsupportedOperationError; } async function jwt(header, claimsSet, key) { if (key.usages.includes("sign") === false) { throw new TypeError('private CryptoKey instances used for signing assertions must include "sign" in their "usages"'); } const input = `${b64u(buf(JSON.stringify(header)))}.${b64u(buf(JSON.stringify(claimsSet)))}`; const signature = b64u(await crypto.subtle.sign(subtleAlgorithm(key), key, buf(input))); return `${input}.${signature}`; } let encodeBase64Url; if (Uint8Array.prototype.toBase64) { encodeBase64Url = input => { if (input instanceof ArrayBuffer) { input = new Uint8Array(input); } return input.toBase64({ alphabet: "base64url", omitPadding: true }); }; } else { const CHUNK_SIZE = 32768; encodeBase64Url = input => { if (input instanceof ArrayBuffer) { input = new Uint8Array(input); } const arr = []; for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) { arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE))); } return btoa(arr.join("")).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_"); }; } function b64u(input) { return encodeBase64Url(input); } class UnsupportedOperationError extends Error { constructor(message) { var _a; super(message !== null && message !== void 0 ? message : "operation not supported"); this.name = this.constructor.name; (_a = Error.captureStackTrace) === null || _a === void 0 ? void 0 : _a.call(Error, this, this.constructor); } } class OperationProcessingError extends Error { constructor(message) { var _a; super(message); this.name = this.constructor.name; (_a = Error.captureStackTrace) === null || _a === void 0 ? void 0 : _a.call(Error, this, this.constructor); } } function psAlg(key) { switch (key.algorithm.hash.name) { case "SHA-256": return "PS256"; default: throw new UnsupportedOperationError("unsupported RsaHashedKeyAlgorithm hash name"); } } function rsAlg(key) { switch (key.algorithm.hash.name) { case "SHA-256": return "RS256"; default: throw new UnsupportedOperationError("unsupported RsaHashedKeyAlgorithm hash name"); } } function esAlg(key) { switch (key.algorithm.namedCurve) { case "P-256": return "ES256"; default: throw new UnsupportedOperationError("unsupported EcKeyAlgorithm namedCurve"); } } function determineJWSAlgorithm(key) { switch (key.algorithm.name) { case "RSA-PSS": return psAlg(key); case "RSASSA-PKCS1-v1_5": return rsAlg(key); case "ECDSA": return esAlg(key); case "Ed25519": return "Ed25519"; default: throw new UnsupportedOperationError("unsupported CryptoKey algorithm name"); } } function isCryptoKey(key) { return key instanceof CryptoKey; } function isPrivateKey(key) { return isCryptoKey(key) && key.type === "private"; } function isPublicKey(key) { return isCryptoKey(key) && key.type === "public"; } function epochTime() { return Math.floor(Date.now() / 1e3); } async function generateProof$1(keypair, htu, htm, nonce, accessToken, additional) { const privateKey = keypair === null || keypair === void 0 ? void 0 : keypair.privateKey; const publicKey = keypair === null || keypair === void 0 ? void 0 : keypair.publicKey; if (!isPrivateKey(privateKey)) { throw new TypeError('"keypair.privateKey" must be a private CryptoKey'); } if (!isPublicKey(publicKey)) { throw new TypeError('"keypair.publicKey" must be a public CryptoKey'); } if (publicKey.extractable !== true) { throw new TypeError('"keypair.publicKey.extractable" must be true'); } if (typeof htu !== "string") { throw new TypeError('"htu" must be a string'); } if (typeof htm !== "string") { throw new TypeError('"htm" must be a string'); } if (nonce !== undefined && typeof nonce !== "string") { throw new TypeError('"nonce" must be a string or undefined'); } if (accessToken !== undefined && typeof accessToken !== "string") { throw new TypeError('"accessToken" must be a string or undefined'); } if (additional !== undefined && (typeof additional !== "object" || additional === null || Array.isArray(additional))) { throw new TypeError('"additional" must be an object'); } return jwt({ alg: determineJWSAlgorithm(privateKey), typ: "dpop+jwt", jwk: await publicJwk(publicKey) }, Object.assign(Object.assign({}, additional), { iat: epochTime(), jti: crypto.randomUUID(), htm: htm, nonce: nonce, htu: htu, ath: accessToken ? b64u(await crypto.subtle.digest("SHA-256", buf(accessToken))) : undefined }), privateKey); } async function publicJwk(key) { const {kty: kty, e: e, n: n, x: x, y: y, crv: crv} = await crypto.subtle.exportKey("jwk", key); return { kty: kty, crv: crv, e: e, n: n, x: x, y: y }; } async function generateKeyPair$1(alg, options) { var _a; let algorithm; if (typeof alg !== "string" || alg.length === 0) { throw new TypeError('"alg" must be a non-empty string'); } switch (alg) { case "PS256": algorithm = { name: "RSA-PSS", hash: "SHA-256", modulusLength: 2048, publicExponent: new Uint8Array([ 1, 0, 1 ]) }; break; case "RS256": algorithm = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256", modulusLength: 2048, publicExponent: new Uint8Array([ 1, 0, 1 ]) }; break; case "ES256": algorithm = { name: "ECDSA", namedCurve: "P-256" }; break; case "Ed25519": algorithm = { name: "Ed25519" }; break; default: throw new UnsupportedOperationError; } return crypto.subtle.generateKey(algorithm, (_a = options === null || options === void 0 ? void 0 : options.extractable) !== null && _a !== void 0 ? _a : false, [ "sign", "verify" ]); } async function calculateThumbprint$1(publicKey) { if (!isPublicKey(publicKey)) { throw new TypeError('"publicKey" must be a public CryptoKey'); } if (publicKey.extractable !== true) { throw new TypeError('"publicKey.extractable" must be true'); } const jwk = await publicJwk(publicKey); let components; switch (jwk.kty) { case "EC": components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }; break; case "OKP": components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x }; break; case "RSA": components = { e: jwk.e, kty: jwk.kty, n: jwk.n }; break; default: throw new UnsupportedOperationError("unsupported JWK kty"); } return b64u(await crypto.subtle.digest({ name: "SHA-256" }, buf(JSON.stringify(components)))); } const DPOP_NONCE_HEADER = "dpop-nonce"; const KEY_PAIR_ALGORITHM = "ES256"; const SUPPORTED_GRANT_TYPES = [ "authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:token-exchange" ]; function generateKeyPair() { return generateKeyPair$1(KEY_PAIR_ALGORITHM, { extractable: false }); } function calculateThumbprint(keyPair) { return calculateThumbprint$1(keyPair.publicKey); } function normalizeUrl(url) { const parsedUrl = new URL(url); parsedUrl.search = ""; parsedUrl.hash = ""; return parsedUrl.href; } function generateProof({keyPair: keyPair, url: url, method: method, nonce: nonce, accessToken: accessToken}) { const normalizedUrl = normalizeUrl(url); return generateProof$1(keyPair, normalizedUrl, method, nonce, accessToken); } function isGrantTypeSupported(grantType) { return SUPPORTED_GRANT_TYPES.includes(grantType); } const sendMessage = (message, to) => new Promise((function(resolve, reject) { const messageChannel = new MessageChannel; messageChannel.port1.onmessage = function(event) { if (event.data.error) { reject(new Error(event.data.error)); } else { resolve(event.data); } messageChannel.port1.close(); }; to.postMessage(message, [ messageChannel.port2 ]); })); const createAbortController = () => new AbortController; const dofetch = async (fetchUrl, fetchOptions) => { const response = await fetch(fetchUrl, fetchOptions); return { ok: response.ok, json: await response.json(), headers: fromEntries(response.headers) }; }; const fetchWithoutWorker = async (fetchUrl, fetchOptions, timeout) => { const controller = createAbortController(); fetchOptions.signal = controller.signal; let timeoutId; return Promise.race([ dofetch(fetchUrl, fetchOptions), new Promise(((_, reject) => { timeoutId = setTimeout((() => { controller.abort(); reject(new Error("Timeout when executing 'fetch'")); }), timeout); })) ]).finally((() => { clearTimeout(timeoutId); })); }; const fetchWithWorker = async (fetchUrl, audience, scope, fetchOptions, timeout, worker, useFormData, useMrrt) => sendMessage({ auth: { audience: audience, scope: scope }, timeout: timeout, fetchUrl: fetchUrl, fetchOptions: fetchOptions, useFormData: useFormData, useMrrt: useMrrt }, worker); const switchFetch = async (fetchUrl, audience, scope, fetchOptions, worker, useFormData, timeout = DEFAULT_FETCH_TIMEOUT_MS, useMrrt) => { if (worker) { return fetchWithWorker(fetchUrl, audience, scope, fetchOptions, timeout, worker, useFormData, useMrrt); } else { return fetchWithoutWorker(fetchUrl, fetchOptions, timeout); } }; async function getJSON(url, timeout, audience, scope, options, worker, useFormData, useMrrt, dpop, isDpopRetry) { if (dpop) { const dpopProof = await dpop.generateProof({ url: url, method: options.method || "GET", nonce: await dpop.getNonce() }); options.headers = Object.assign(Object.assign({}, options.headers), { dpop: dpopProof }); } let fetchError = null; let response; for (let i = 0; i < DEFAULT_SILENT_TOKEN_RETRY_COUNT; i++) { try { response = await switchFetch(url, audience, scope, options, worker, useFormData, timeout, useMrrt); fetchError = null; break; } catch (e) { fetchError = e; } } if (fetchError) { throw fetchError; } const _a = response.json, {error: error, error_description: error_description} = _a, data = __rest(_a, [ "error", "error_description" ]), {headers: headers, ok: ok} = response; let newDpopNonce; if (dpop) { newDpopNonce = headers[DPOP_NONCE_HEADER]; if (newDpopNonce) { await dpop.setNonce(newDpopNonce); } } if (!ok) { const errorMessage = error_description || `HTTP error. Unable to fetch ${url}`; if (error === "mfa_required") { throw new MfaRequiredError(error, errorMessage, data.mfa_token); } if (error === "missing_refresh_token") { throw new MissingRefreshTokenError(audience, scope); } if (error === "use_dpop_nonce") { if (!dpop || !newDpopNonce || isDpopRetry) { throw new UseDpopNonceError(newDpopNonce); } return getJSON(url, timeout, audience, scope, options, worker, useFormData, useMrrt, dpop, true); } throw new GenericError(error || "request_error", errorMessage); } return data; } async function oauthToken(_a, worker) { var {baseUrl: baseUrl, timeout: timeout, audience: audience, scope: scope, auth0Client: auth0Client, useFormData: useFormData, useMrrt: useMrrt, dpop: dpop} = _a, options = __rest(_a, [ "baseUrl", "timeout", "audience", "scope", "auth0Client", "useFormData", "useMrrt", "dpop" ]); const isTokenExchange = options.grant_type === "urn:ietf:params:oauth:grant-type:token-exchange"; const refreshWithMrrt = options.grant_type === "refresh_token" && useMrrt; const allParams = Object.assign(Object.assign(Object.assign(Object.assign({}, options), isTokenExchange && audience && { audience: audience }), isTokenExchange && scope && { scope: scope }), refreshWithMrrt && { audience: audience, scope: scope }); const body = useFormData ? createQueryParams(allParams) : JSON.stringify(allParams); const isDpopSupported = isGrantTypeSupported(options.grant_type); return await getJSON(`${baseUrl}/oauth/token`, timeout, audience || DEFAULT_AUDIENCE, scope, { method: "POST", body: body, headers: { "Content-Type": useFormData ? "application/x-www-form-urlencoded" : "application/json", "Auth0-Client": btoa(JSON.stringify(stripAuth0Client(auth0Client || DEFAULT_AUTH0_CLIENT))) } }, worker, useFormData, useMrrt, isDpopSupported ? dpop : undefined); } const dedupe = arr => Array.from(new Set(arr)); const getUniqueScopes = (...scopes) => dedupe(scopes.filter(Boolean).join(" ").trim().split(/\s+/)).join(" "); const injectDefaultScopes = (authScopes, openIdScope, ...extraScopes) => { if (typeof authScopes !== "object") { return { [DEFAULT_AUDIENCE]: getUniqueScopes(openIdScope, authScopes, ...extraScopes) }; } let requestedScopes = { [DEFAULT_AUDIENCE]: getUniqueScopes(openIdScope, ...extraScopes) }; Object.keys(authScopes).forEach((key => { const audienceScopes = authScopes[key]; requestedScopes[key] = getUniqueScopes(openIdScope, audienceScopes, ...extraScopes); })); return requestedScopes; }; const scopesToRequest = (authScopes, methodScopes, audience) => { let scope; if (audience) { scope = authScopes[audience]; } if (!scope) { scope = authScopes[DEFAULT_AUDIENCE]; } return getUniqueScopes(scope, methodScopes); }; const CACHE_KEY_PREFIX = "@@auth0spajs@@"; const CACHE_KEY_ID_TOKEN_SUFFIX = "@@user@@"; class CacheKey { constructor(data, prefix = CACHE_KEY_PREFIX, suffix) { this.prefix = prefix; this.suffix = suffix; this.clientId = data.clientId; this.scope = data.scope; this.audience = data.audience; } toKey() { return [ this.prefix, this.clientId, this.audience, this.scope, this.suffix ].filter(Boolean).join("::"); } static fromKey(key) { const [prefix, clientId, audience, scope] = key.split("::"); return new CacheKey({ clientId: clientId, scope: scope, audience: audience }, prefix); } static fromCacheEntry(entry) { const {scope: scope, audience: audience, client_id: clientId} = entry; return new CacheKey({ scope: scope, audience: audience, clientId: clientId }); } } class LocalStorageCache { set(key, entry) { localStorage.setItem(key, JSON.stringify(entry)); } get(key) { const json = window.localStorage.getItem(key); if (!json) ret