@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
JavaScript
"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