@auth0/auth0-spa-js 2.4.0 → 2.5.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.
package/README.md CHANGED
@@ -29,7 +29,7 @@ npm install @auth0/auth0-spa-js
29
29
  From the CDN:
30
30
 
31
31
  ```html
32
- <script src="https://cdn.auth0.com/js/auth0-spa-js/2.4/auth0-spa-js.production.js"></script>
32
+ <script src="https://cdn.auth0.com/js/auth0-spa-js/2.5/auth0-spa-js.production.js"></script>
33
33
  ```
34
34
 
35
35
  ### Configure Auth0
@@ -540,7 +540,7 @@
540
540
  exports.default = SuperTokensLock;
541
541
  }));
542
542
  var Lock = unwrapExports(browserTabsLock);
543
- var version = "2.4.0";
543
+ var version = "2.5.0";
544
544
  const DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS = 60;
545
545
  const DEFAULT_POPUP_CONFIG_OPTIONS = {
546
546
  timeoutInSeconds: DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS
@@ -1114,7 +1114,7 @@
1114
1114
  clearTimeout(timeoutId);
1115
1115
  }));
1116
1116
  };
1117
- const fetchWithWorker = async (fetchUrl, audience, scope, fetchOptions, timeout, worker, useFormData) => sendMessage({
1117
+ const fetchWithWorker = async (fetchUrl, audience, scope, fetchOptions, timeout, worker, useFormData, useMrrt) => sendMessage({
1118
1118
  auth: {
1119
1119
  audience: audience,
1120
1120
  scope: scope
@@ -1122,16 +1122,17 @@
1122
1122
  timeout: timeout,
1123
1123
  fetchUrl: fetchUrl,
1124
1124
  fetchOptions: fetchOptions,
1125
- useFormData: useFormData
1125
+ useFormData: useFormData,
1126
+ useMrrt: useMrrt
1126
1127
  }, worker);
1127
- const switchFetch = async (fetchUrl, audience, scope, fetchOptions, worker, useFormData, timeout = DEFAULT_FETCH_TIMEOUT_MS) => {
1128
+ const switchFetch = async (fetchUrl, audience, scope, fetchOptions, worker, useFormData, timeout = DEFAULT_FETCH_TIMEOUT_MS, useMrrt) => {
1128
1129
  if (worker) {
1129
- return fetchWithWorker(fetchUrl, audience, scope, fetchOptions, timeout, worker, useFormData);
1130
+ return fetchWithWorker(fetchUrl, audience, scope, fetchOptions, timeout, worker, useFormData, useMrrt);
1130
1131
  } else {
1131
1132
  return fetchWithoutWorker(fetchUrl, fetchOptions, timeout);
1132
1133
  }
1133
1134
  };
1134
- async function getJSON(url, timeout, audience, scope, options, worker, useFormData, dpop, isDpopRetry) {
1135
+ async function getJSON(url, timeout, audience, scope, options, worker, useFormData, useMrrt, dpop, isDpopRetry) {
1135
1136
  if (dpop) {
1136
1137
  const dpopProof = await dpop.generateProof({
1137
1138
  url: url,
@@ -1146,7 +1147,7 @@
1146
1147
  let response;
1147
1148
  for (let i = 0; i < DEFAULT_SILENT_TOKEN_RETRY_COUNT; i++) {
1148
1149
  try {
1149
- response = await switchFetch(url, audience, scope, options, worker, useFormData, timeout);
1150
+ response = await switchFetch(url, audience, scope, options, worker, useFormData, timeout, useMrrt);
1150
1151
  fetchError = null;
1151
1152
  break;
1152
1153
  } catch (e) {
@@ -1176,19 +1177,23 @@
1176
1177
  if (!dpop || !newDpopNonce || isDpopRetry) {
1177
1178
  throw new UseDpopNonceError(newDpopNonce);
1178
1179
  }
1179
- return getJSON(url, timeout, audience, scope, options, worker, useFormData, dpop, true);
1180
+ return getJSON(url, timeout, audience, scope, options, worker, useFormData, useMrrt, dpop, true);
1180
1181
  }
1181
1182
  throw new GenericError(error || "request_error", errorMessage);
1182
1183
  }
1183
1184
  return data;
1184
1185
  }
1185
1186
  async function oauthToken(_a, worker) {
1186
- var {baseUrl: baseUrl, timeout: timeout, audience: audience, scope: scope, auth0Client: auth0Client, useFormData: useFormData, dpop: dpop} = _a, options = __rest(_a, [ "baseUrl", "timeout", "audience", "scope", "auth0Client", "useFormData", "dpop" ]);
1187
+ 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" ]);
1187
1188
  const isTokenExchange = options.grant_type === "urn:ietf:params:oauth:grant-type:token-exchange";
1188
- const allParams = Object.assign(Object.assign(Object.assign({}, options), isTokenExchange && audience && {
1189
+ const refreshWithMrrt = options.grant_type === "refresh_token" && useMrrt;
1190
+ const allParams = Object.assign(Object.assign(Object.assign(Object.assign({}, options), isTokenExchange && audience && {
1189
1191
  audience: audience
1190
1192
  }), isTokenExchange && scope && {
1191
1193
  scope: scope
1194
+ }), refreshWithMrrt && {
1195
+ audience: audience,
1196
+ scope: scope
1192
1197
  });
1193
1198
  const body = useFormData ? createQueryParams(allParams) : JSON.stringify(allParams);
1194
1199
  const isDpopSupported = isGrantTypeSupported(options.grant_type);
@@ -1199,7 +1204,7 @@
1199
1204
  "Content-Type": useFormData ? "application/x-www-form-urlencoded" : "application/json",
1200
1205
  "Auth0-Client": btoa(JSON.stringify(auth0Client || DEFAULT_AUTH0_CLIENT))
1201
1206
  }
1202
- }, worker, useFormData, isDpopSupported ? dpop : undefined);
1207
+ }, worker, useFormData, useMrrt, isDpopSupported ? dpop : undefined);
1203
1208
  }
1204
1209
  const dedupe = arr => Array.from(new Set(arr));
1205
1210
  const getUniqueScopes = (...scopes) => dedupe(scopes.filter(Boolean).join(" ").trim().split(/\s+/)).join(" ");
@@ -1318,7 +1323,7 @@
1318
1323
  decodedToken: entry.decodedToken
1319
1324
  };
1320
1325
  }
1321
- async get(cacheKey, expiryAdjustmentSeconds = DEFAULT_EXPIRY_ADJUSTMENT_SECONDS) {
1326
+ async get(cacheKey, expiryAdjustmentSeconds = DEFAULT_EXPIRY_ADJUSTMENT_SECONDS, useMrrt = false, cacheMode) {
1322
1327
  var _a;
1323
1328
  let wrappedEntry = await this.cache.get(cacheKey.toKey());
1324
1329
  if (!wrappedEntry) {
@@ -1328,6 +1333,9 @@
1328
1333
  if (matchedKey) {
1329
1334
  wrappedEntry = await this.cache.get(matchedKey);
1330
1335
  }
1336
+ if (!matchedKey && useMrrt && cacheMode !== "cache-only") {
1337
+ return this.getEntryWithRefreshToken(cacheKey, keys);
1338
+ }
1331
1339
  }
1332
1340
  if (!wrappedEntry) {
1333
1341
  return;
@@ -1336,11 +1344,7 @@
1336
1344
  const nowSeconds = Math.floor(now / 1e3);
1337
1345
  if (wrappedEntry.expiresAt - expiryAdjustmentSeconds < nowSeconds) {
1338
1346
  if (wrappedEntry.body.refresh_token) {
1339
- wrappedEntry.body = {
1340
- refresh_token: wrappedEntry.body.refresh_token
1341
- };
1342
- await this.cache.set(cacheKey.toKey(), wrappedEntry);
1343
- return wrappedEntry.body;
1347
+ return this.modifiedCachedEntry(wrappedEntry, cacheKey);
1344
1348
  }
1345
1349
  await this.cache.remove(cacheKey.toKey());
1346
1350
  await ((_a = this.keyManifest) === null || _a === void 0 ? void 0 : _a.remove(cacheKey.toKey()));
@@ -1348,6 +1352,19 @@
1348
1352
  }
1349
1353
  return wrappedEntry.body;
1350
1354
  }
1355
+ async modifiedCachedEntry(wrappedEntry, cacheKey) {
1356
+ wrappedEntry.body = {
1357
+ refresh_token: wrappedEntry.body.refresh_token,
1358
+ audience: wrappedEntry.body.audience,
1359
+ scope: wrappedEntry.body.scope
1360
+ };
1361
+ await this.cache.set(cacheKey.toKey(), wrappedEntry);
1362
+ return {
1363
+ refresh_token: wrappedEntry.body.refresh_token,
1364
+ audience: wrappedEntry.body.audience,
1365
+ scope: wrappedEntry.body.scope
1366
+ };
1367
+ }
1351
1368
  async set(entry) {
1352
1369
  var _a;
1353
1370
  const cacheKey = new CacheKey({
@@ -1400,6 +1417,33 @@
1400
1417
  return cacheKey.prefix === CACHE_KEY_PREFIX && cacheKey.clientId === keyToMatch.clientId && cacheKey.audience === keyToMatch.audience && hasAllScopes;
1401
1418
  }))[0];
1402
1419
  }
1420
+ async getEntryWithRefreshToken(keyToMatch, allKeys) {
1421
+ var _a;
1422
+ for (const key of allKeys) {
1423
+ const cacheKey = CacheKey.fromKey(key);
1424
+ if (cacheKey.prefix === CACHE_KEY_PREFIX && cacheKey.clientId === keyToMatch.clientId) {
1425
+ const cachedEntry = await this.cache.get(key);
1426
+ if ((_a = cachedEntry === null || cachedEntry === void 0 ? void 0 : cachedEntry.body) === null || _a === void 0 ? void 0 : _a.refresh_token) {
1427
+ return this.modifiedCachedEntry(cachedEntry, keyToMatch);
1428
+ }
1429
+ }
1430
+ }
1431
+ return undefined;
1432
+ }
1433
+ async updateEntry(oldRefreshToken, newRefreshToken) {
1434
+ var _a;
1435
+ const allKeys = await this.getCacheKeys();
1436
+ if (!allKeys) return;
1437
+ for (const key of allKeys) {
1438
+ const entry = await this.cache.get(key);
1439
+ if (((_a = entry === null || entry === void 0 ? void 0 : entry.body) === null || _a === void 0 ? void 0 : _a.refresh_token) === oldRefreshToken) {
1440
+ const cacheEntry = Object.assign(Object.assign({}, entry.body), {
1441
+ refresh_token: newRefreshToken
1442
+ });
1443
+ await this.set(cacheEntry);
1444
+ }
1445
+ }
1446
+ }
1403
1447
  }
1404
1448
  const TRANSACTION_STORAGE_KEY_PREFIX = "a0.spajs.txs";
1405
1449
  class TransactionManager {
@@ -1741,7 +1785,7 @@
1741
1785
  return new Worker(url, options);
1742
1786
  };
1743
1787
  }
1744
- var WorkerFactory = createBase64WorkerFactory("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24oKSB7CiAgICAidXNlIHN0cmljdCI7CiAgICBjbGFzcyBHZW5lcmljRXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgICAgICAgY29uc3RydWN0b3IoZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uKSB7CiAgICAgICAgICAgIHN1cGVyKGVycm9yX2Rlc2NyaXB0aW9uKTsKICAgICAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yOwogICAgICAgICAgICB0aGlzLmVycm9yX2Rlc2NyaXB0aW9uID0gZXJyb3JfZGVzY3JpcHRpb247CiAgICAgICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBHZW5lcmljRXJyb3IucHJvdG90eXBlKTsKICAgICAgICB9CiAgICAgICAgc3RhdGljIGZyb21QYXlsb2FkKHtlcnJvcjogZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uOiBlcnJvcl9kZXNjcmlwdGlvbn0pIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmljRXJyb3IoZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uKTsKICAgICAgICB9CiAgICB9CiAgICBjbGFzcyBNaXNzaW5nUmVmcmVzaFRva2VuRXJyb3IgZXh0ZW5kcyBHZW5lcmljRXJyb3IgewogICAgICAgIGNvbnN0cnVjdG9yKGF1ZGllbmNlLCBzY29wZSkgewogICAgICAgICAgICBzdXBlcigibWlzc2luZ19yZWZyZXNoX3Rva2VuIiwgYE1pc3NpbmcgUmVmcmVzaCBUb2tlbiAoYXVkaWVuY2U6ICcke3ZhbHVlT3JFbXB0eVN0cmluZyhhdWRpZW5jZSwgWyAiZGVmYXVsdCIgXSl9Jywgc2NvcGU6ICcke3ZhbHVlT3JFbXB0eVN0cmluZyhzY29wZSl9JylgKTsKICAgICAgICAgICAgdGhpcy5hdWRpZW5jZSA9IGF1ZGllbmNlOwogICAgICAgICAgICB0aGlzLnNjb3BlID0gc2NvcGU7CiAgICAgICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBNaXNzaW5nUmVmcmVzaFRva2VuRXJyb3IucHJvdG90eXBlKTsKICAgICAgICB9CiAgICB9CiAgICBmdW5jdGlvbiB2YWx1ZU9yRW1wdHlTdHJpbmcodmFsdWUsIGV4Y2x1ZGUgPSBbXSkgewogICAgICAgIHJldHVybiB2YWx1ZSAmJiAhZXhjbHVkZS5pbmNsdWRlcyh2YWx1ZSkgPyB2YWx1ZSA6ICIiOwogICAgfQogICAgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHsKICAgICAgICB2YXIgdCA9IHt9OwogICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKSB0W3BdID0gc1twXTsKICAgICAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSAiZnVuY3Rpb24iKSBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSkgdFtwW2ldXSA9IHNbcFtpXV07CiAgICAgICAgfQogICAgICAgIHJldHVybiB0OwogICAgfQogICAgdHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gImZ1bmN0aW9uIiA/IFN1cHByZXNzZWRFcnJvciA6IGZ1bmN0aW9uKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7CiAgICAgICAgdmFyIGUgPSBuZXcgRXJyb3IobWVzc2FnZSk7CiAgICAgICAgcmV0dXJuIGUubmFtZSA9ICJTdXBwcmVzc2VkRXJyb3IiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7CiAgICB9OwogICAgY29uc3Qgc3RyaXBVbmRlZmluZWQgPSBwYXJhbXMgPT4gT2JqZWN0LmtleXMocGFyYW1zKS5maWx0ZXIoKGsgPT4gdHlwZW9mIHBhcmFtc1trXSAhPT0gInVuZGVmaW5lZCIpKS5yZWR1Y2UoKChhY2MsIGtleSkgPT4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBhY2MpLCB7CiAgICAgICAgW2tleV06IHBhcmFtc1trZXldCiAgICB9KSksIHt9KTsKICAgIGNvbnN0IGNyZWF0ZVF1ZXJ5UGFyYW1zID0gX2EgPT4gewogICAgICAgIHZhciB7Y2xpZW50SWQ6IGNsaWVudF9pZH0gPSBfYSwgcGFyYW1zID0gX19yZXN0KF9hLCBbICJjbGllbnRJZCIgXSk7CiAgICAgICAgcmV0dXJuIG5ldyBVUkxTZWFyY2hQYXJhbXMoc3RyaXBVbmRlZmluZWQoT2JqZWN0LmFzc2lnbih7CiAgICAgICAgICAgIGNsaWVudF9pZDogY2xpZW50X2lkCiAgICAgICAgfSwgcGFyYW1zKSkpLnRvU3RyaW5nKCk7CiAgICB9OwogICAgY29uc3QgZnJvbUVudHJpZXMgPSBpdGVyYWJsZSA9PiBbIC4uLml0ZXJhYmxlIF0ucmVkdWNlKCgob2JqLCBba2V5LCB2YWxdKSA9PiB7CiAgICAgICAgb2JqW2tleV0gPSB2YWw7CiAgICAgICAgcmV0dXJuIG9iajsKICAgIH0pLCB7fSk7CiAgICBsZXQgcmVmcmVzaFRva2VucyA9IHt9OwogICAgY29uc3QgY2FjaGVLZXkgPSAoYXVkaWVuY2UsIHNjb3BlKSA9PiBgJHthdWRpZW5jZX18JHtzY29wZX1gOwogICAgY29uc3QgZ2V0UmVmcmVzaFRva2VuID0gKGF1ZGllbmNlLCBzY29wZSkgPT4gcmVmcmVzaFRva2Vuc1tjYWNoZUtleShhdWRpZW5jZSwgc2NvcGUpXTsKICAgIGNvbnN0IHNldFJlZnJlc2hUb2tlbiA9IChyZWZyZXNoVG9rZW4sIGF1ZGllbmNlLCBzY29wZSkgPT4gcmVmcmVzaFRva2Vuc1tjYWNoZUtleShhdWRpZW5jZSwgc2NvcGUpXSA9IHJlZnJlc2hUb2tlbjsKICAgIGNvbnN0IGRlbGV0ZVJlZnJlc2hUb2tlbiA9IChhdWRpZW5jZSwgc2NvcGUpID0+IGRlbGV0ZSByZWZyZXNoVG9rZW5zW2NhY2hlS2V5KGF1ZGllbmNlLCBzY29wZSldOwogICAgY29uc3Qgd2FpdCA9IHRpbWUgPT4gbmV3IFByb21pc2UoKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCB0aW1lKSkpOwogICAgY29uc3QgZm9ybURhdGFUb09iamVjdCA9IGZvcm1EYXRhID0+IHsKICAgICAgICBjb25zdCBxdWVyeVBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoZm9ybURhdGEpOwogICAgICAgIGNvbnN0IHBhcnNlZFF1ZXJ5ID0ge307CiAgICAgICAgcXVlcnlQYXJhbXMuZm9yRWFjaCgoKHZhbCwga2V5KSA9PiB7CiAgICAgICAgICAgIHBhcnNlZFF1ZXJ5W2tleV0gPSB2YWw7CiAgICAgICAgfSkpOwogICAgICAgIHJldHVybiBwYXJzZWRRdWVyeTsKICAgIH07CiAgICBjb25zdCBtZXNzYWdlSGFuZGxlciA9IGFzeW5jICh7ZGF0YToge3RpbWVvdXQ6IHRpbWVvdXQsIGF1dGg6IGF1dGgsIGZldGNoVXJsOiBmZXRjaFVybCwgZmV0Y2hPcHRpb25zOiBmZXRjaE9wdGlvbnMsIHVzZUZvcm1EYXRhOiB1c2VGb3JtRGF0YX0sIHBvcnRzOiBbcG9ydF19KSA9PiB7CiAgICAgICAgbGV0IGhlYWRlcnMgPSB7fTsKICAgICAgICBsZXQganNvbjsKICAgICAgICBjb25zdCB7YXVkaWVuY2U6IGF1ZGllbmNlLCBzY29wZTogc2NvcGV9ID0gYXV0aCB8fCB7fTsKICAgICAgICB0cnkgewogICAgICAgICAgICBjb25zdCBib2R5ID0gdXNlRm9ybURhdGEgPyBmb3JtRGF0YVRvT2JqZWN0KGZldGNoT3B0aW9ucy5ib2R5KSA6IEpTT04ucGFyc2UoZmV0Y2hPcHRpb25zLmJvZHkpOwogICAgICAgICAgICBpZiAoIWJvZHkucmVmcmVzaF90b2tlbiAmJiBib2R5LmdyYW50X3R5cGUgPT09ICJyZWZyZXNoX3Rva2VuIikgewogICAgICAgICAgICAgICAgY29uc3QgcmVmcmVzaFRva2VuID0gZ2V0UmVmcmVzaFRva2VuKGF1ZGllbmNlLCBzY29wZSk7CiAgICAgICAgICAgICAgICBpZiAoIXJlZnJlc2hUb2tlbikgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNaXNzaW5nUmVmcmVzaFRva2VuRXJyb3IoYXVkaWVuY2UsIHNjb3BlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZldGNoT3B0aW9ucy5ib2R5ID0gdXNlRm9ybURhdGEgPyBjcmVhdGVRdWVyeVBhcmFtcyhPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGJvZHkpLCB7CiAgICAgICAgICAgICAgICAgICAgcmVmcmVzaF90b2tlbjogcmVmcmVzaFRva2VuCiAgICAgICAgICAgICAgICB9KSkgOiBKU09OLnN0cmluZ2lmeShPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGJvZHkpLCB7CiAgICAgICAgICAgICAgICAgICAgcmVmcmVzaF90b2tlbjogcmVmcmVzaFRva2VuCiAgICAgICAgICAgICAgICB9KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGV0IGFib3J0Q29udHJvbGxlcjsKICAgICAgICAgICAgaWYgKHR5cGVvZiBBYm9ydENvbnRyb2xsZXIgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgICAgIGFib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXI7CiAgICAgICAgICAgICAgICBmZXRjaE9wdGlvbnMuc2lnbmFsID0gYWJvcnRDb250cm9sbGVyLnNpZ25hbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgcmVzcG9uc2U7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXNwb25zZSA9IGF3YWl0IFByb21pc2UucmFjZShbIHdhaXQodGltZW91dCksIGZldGNoKGZldGNoVXJsLCBPYmplY3QuYXNzaWduKHt9LCBmZXRjaE9wdGlvbnMpKSBdKTsKICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgICAgIHBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvci5tZXNzYWdlCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIXJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICBpZiAoYWJvcnRDb250cm9sbGVyKSBhYm9ydENvbnRyb2xsZXIuYWJvcnQoKTsKICAgICAgICAgICAgICAgIHBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICAgICAgICAgIGVycm9yOiAiVGltZW91dCB3aGVuIGV4ZWN1dGluZyAnZmV0Y2gnIgogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaGVhZGVycyA9IGZyb21FbnRyaWVzKHJlc3BvbnNlLmhlYWRlcnMpOwogICAgICAgICAgICBqc29uID0gYXdhaXQgcmVzcG9uc2UuanNvbigpOwogICAgICAgICAgICBpZiAoanNvbi5yZWZyZXNoX3Rva2VuKSB7CiAgICAgICAgICAgICAgICBzZXRSZWZyZXNoVG9rZW4oanNvbi5yZWZyZXNoX3Rva2VuLCBhdWRpZW5jZSwgc2NvcGUpOwogICAgICAgICAgICAgICAgZGVsZXRlIGpzb24ucmVmcmVzaF90b2tlbjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGRlbGV0ZVJlZnJlc2hUb2tlbihhdWRpZW5jZSwgc2NvcGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICAgICAgb2s6IHJlc3BvbnNlLm9rLAogICAgICAgICAgICAgICAganNvbjoganNvbiwKICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnMKICAgICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgcG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICBvazogZmFsc2UsCiAgICAgICAgICAgICAgICBqc29uOiB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLmVycm9yLAogICAgICAgICAgICAgICAgICAgIGVycm9yX2Rlc2NyaXB0aW9uOiBlcnJvci5tZXNzYWdlCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVycwogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9OwogICAgewogICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCBtZXNzYWdlSGFuZGxlcik7CiAgICB9Cn0pKCk7Cgo=", null, false);
1788
+ var WorkerFactory = createBase64WorkerFactory("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24oKSB7CiAgICAidXNlIHN0cmljdCI7CiAgICBjbGFzcyBHZW5lcmljRXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgICAgICAgY29uc3RydWN0b3IoZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uKSB7CiAgICAgICAgICAgIHN1cGVyKGVycm9yX2Rlc2NyaXB0aW9uKTsKICAgICAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yOwogICAgICAgICAgICB0aGlzLmVycm9yX2Rlc2NyaXB0aW9uID0gZXJyb3JfZGVzY3JpcHRpb247CiAgICAgICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBHZW5lcmljRXJyb3IucHJvdG90eXBlKTsKICAgICAgICB9CiAgICAgICAgc3RhdGljIGZyb21QYXlsb2FkKHtlcnJvcjogZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uOiBlcnJvcl9kZXNjcmlwdGlvbn0pIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmljRXJyb3IoZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uKTsKICAgICAgICB9CiAgICB9CiAgICBjbGFzcyBNaXNzaW5nUmVmcmVzaFRva2VuRXJyb3IgZXh0ZW5kcyBHZW5lcmljRXJyb3IgewogICAgICAgIGNvbnN0cnVjdG9yKGF1ZGllbmNlLCBzY29wZSkgewogICAgICAgICAgICBzdXBlcigibWlzc2luZ19yZWZyZXNoX3Rva2VuIiwgYE1pc3NpbmcgUmVmcmVzaCBUb2tlbiAoYXVkaWVuY2U6ICcke3ZhbHVlT3JFbXB0eVN0cmluZyhhdWRpZW5jZSwgWyAiZGVmYXVsdCIgXSl9Jywgc2NvcGU6ICcke3ZhbHVlT3JFbXB0eVN0cmluZyhzY29wZSl9JylgKTsKICAgICAgICAgICAgdGhpcy5hdWRpZW5jZSA9IGF1ZGllbmNlOwogICAgICAgICAgICB0aGlzLnNjb3BlID0gc2NvcGU7CiAgICAgICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBNaXNzaW5nUmVmcmVzaFRva2VuRXJyb3IucHJvdG90eXBlKTsKICAgICAgICB9CiAgICB9CiAgICBmdW5jdGlvbiB2YWx1ZU9yRW1wdHlTdHJpbmcodmFsdWUsIGV4Y2x1ZGUgPSBbXSkgewogICAgICAgIHJldHVybiB2YWx1ZSAmJiAhZXhjbHVkZS5pbmNsdWRlcyh2YWx1ZSkgPyB2YWx1ZSA6ICIiOwogICAgfQogICAgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHsKICAgICAgICB2YXIgdCA9IHt9OwogICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKSB0W3BdID0gc1twXTsKICAgICAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSAiZnVuY3Rpb24iKSBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSkgdFtwW2ldXSA9IHNbcFtpXV07CiAgICAgICAgfQogICAgICAgIHJldHVybiB0OwogICAgfQogICAgdHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gImZ1bmN0aW9uIiA/IFN1cHByZXNzZWRFcnJvciA6IGZ1bmN0aW9uKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7CiAgICAgICAgdmFyIGUgPSBuZXcgRXJyb3IobWVzc2FnZSk7CiAgICAgICAgcmV0dXJuIGUubmFtZSA9ICJTdXBwcmVzc2VkRXJyb3IiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7CiAgICB9OwogICAgY29uc3Qgc3RyaXBVbmRlZmluZWQgPSBwYXJhbXMgPT4gT2JqZWN0LmtleXMocGFyYW1zKS5maWx0ZXIoKGsgPT4gdHlwZW9mIHBhcmFtc1trXSAhPT0gInVuZGVmaW5lZCIpKS5yZWR1Y2UoKChhY2MsIGtleSkgPT4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBhY2MpLCB7CiAgICAgICAgW2tleV06IHBhcmFtc1trZXldCiAgICB9KSksIHt9KTsKICAgIGNvbnN0IGNyZWF0ZVF1ZXJ5UGFyYW1zID0gX2EgPT4gewogICAgICAgIHZhciB7Y2xpZW50SWQ6IGNsaWVudF9pZH0gPSBfYSwgcGFyYW1zID0gX19yZXN0KF9hLCBbICJjbGllbnRJZCIgXSk7CiAgICAgICAgcmV0dXJuIG5ldyBVUkxTZWFyY2hQYXJhbXMoc3RyaXBVbmRlZmluZWQoT2JqZWN0LmFzc2lnbih7CiAgICAgICAgICAgIGNsaWVudF9pZDogY2xpZW50X2lkCiAgICAgICAgfSwgcGFyYW1zKSkpLnRvU3RyaW5nKCk7CiAgICB9OwogICAgY29uc3QgZnJvbUVudHJpZXMgPSBpdGVyYWJsZSA9PiBbIC4uLml0ZXJhYmxlIF0ucmVkdWNlKCgob2JqLCBba2V5LCB2YWxdKSA9PiB7CiAgICAgICAgb2JqW2tleV0gPSB2YWw7CiAgICAgICAgcmV0dXJuIG9iajsKICAgIH0pLCB7fSk7CiAgICBsZXQgcmVmcmVzaFRva2VucyA9IHt9OwogICAgY29uc3QgY2FjaGVLZXkgPSAoYXVkaWVuY2UsIHNjb3BlKSA9PiBgJHthdWRpZW5jZX18JHtzY29wZX1gOwogICAgY29uc3QgY2FjaGVLZXlDb250YWluc0F1ZGllbmNlID0gKGF1ZGllbmNlLCBjYWNoZUtleSkgPT4gY2FjaGVLZXkuc3RhcnRzV2l0aChgJHthdWRpZW5jZX18YCk7CiAgICBjb25zdCBnZXRSZWZyZXNoVG9rZW4gPSAoYXVkaWVuY2UsIHNjb3BlKSA9PiByZWZyZXNoVG9rZW5zW2NhY2hlS2V5KGF1ZGllbmNlLCBzY29wZSldOwogICAgY29uc3Qgc2V0UmVmcmVzaFRva2VuID0gKHJlZnJlc2hUb2tlbiwgYXVkaWVuY2UsIHNjb3BlKSA9PiByZWZyZXNoVG9rZW5zW2NhY2hlS2V5KGF1ZGllbmNlLCBzY29wZSldID0gcmVmcmVzaFRva2VuOwogICAgY29uc3QgZGVsZXRlUmVmcmVzaFRva2VuID0gKGF1ZGllbmNlLCBzY29wZSkgPT4gZGVsZXRlIHJlZnJlc2hUb2tlbnNbY2FjaGVLZXkoYXVkaWVuY2UsIHNjb3BlKV07CiAgICBjb25zdCB3YWl0ID0gdGltZSA9PiBuZXcgUHJvbWlzZSgocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIHRpbWUpKSk7CiAgICBjb25zdCBmb3JtRGF0YVRvT2JqZWN0ID0gZm9ybURhdGEgPT4gewogICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhmb3JtRGF0YSk7CiAgICAgICAgY29uc3QgcGFyc2VkUXVlcnkgPSB7fTsKICAgICAgICBxdWVyeVBhcmFtcy5mb3JFYWNoKCgodmFsLCBrZXkpID0+IHsKICAgICAgICAgICAgcGFyc2VkUXVlcnlba2V5XSA9IHZhbDsKICAgICAgICB9KSk7CiAgICAgICAgcmV0dXJuIHBhcnNlZFF1ZXJ5OwogICAgfTsKICAgIGNvbnN0IHVwZGF0ZVJlZnJlc2hUb2tlbnMgPSAob2xkUmVmcmVzaFRva2VuLCBuZXdSZWZyZXNoVG9rZW4pID0+IHsKICAgICAgICBPYmplY3QuZW50cmllcyhyZWZyZXNoVG9rZW5zKS5mb3JFYWNoKCgoW2tleSwgdG9rZW5dKSA9PiB7CiAgICAgICAgICAgIGlmICh0b2tlbiA9PT0gb2xkUmVmcmVzaFRva2VuKSB7CiAgICAgICAgICAgICAgICByZWZyZXNoVG9rZW5zW2tleV0gPSBuZXdSZWZyZXNoVG9rZW47CiAgICAgICAgICAgIH0KICAgICAgICB9KSk7CiAgICB9OwogICAgY29uc3QgY2hlY2tEb3duc2NvcGluZyA9IChzY29wZSwgYXVkaWVuY2UpID0+IHsKICAgICAgICBjb25zdCBmaW5kQ29pbmNpZGVuY2UgPSBPYmplY3Qua2V5cyhyZWZyZXNoVG9rZW5zKS5maW5kKChrZXkgPT4gewogICAgICAgICAgICBpZiAoa2V5ICE9PSAibGF0ZXN0X3JlZnJlc2hfdG9rZW4iKSB7CiAgICAgICAgICAgICAgICBjb25zdCBpc1NhbWVBdWRpZW5jZSA9IGNhY2hlS2V5Q29udGFpbnNBdWRpZW5jZShhdWRpZW5jZSwga2V5KTsKICAgICAgICAgICAgICAgIGNvbnN0IHNjb3Blc0tleSA9IGtleS5zcGxpdCgifCIpWzFdLnNwbGl0KCIgIik7CiAgICAgICAgICAgICAgICBjb25zdCByZXF1ZXN0ZWRTY29wZXMgPSBzY29wZS5zcGxpdCgiICIpOwogICAgICAgICAgICAgICAgY29uc3Qgc2NvcGVzQXJlSW5jbHVkZWQgPSByZXF1ZXN0ZWRTY29wZXMuZXZlcnkoKGtleSA9PiBzY29wZXNLZXkuaW5jbHVkZXMoa2V5KSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIGlzU2FtZUF1ZGllbmNlICYmIHNjb3Blc0FyZUluY2x1ZGVkOwogICAgICAgICAgICB9CiAgICAgICAgfSkpOwogICAgICAgIHJldHVybiBmaW5kQ29pbmNpZGVuY2UgPyB0cnVlIDogZmFsc2U7CiAgICB9OwogICAgY29uc3QgbWVzc2FnZUhhbmRsZXIgPSBhc3luYyAoe2RhdGE6IHt0aW1lb3V0OiB0aW1lb3V0LCBhdXRoOiBhdXRoLCBmZXRjaFVybDogZmV0Y2hVcmwsIGZldGNoT3B0aW9uczogZmV0Y2hPcHRpb25zLCB1c2VGb3JtRGF0YTogdXNlRm9ybURhdGEsIHVzZU1ycnQ6IHVzZU1ycnR9LCBwb3J0czogW3BvcnRdfSkgPT4gewogICAgICAgIGxldCBoZWFkZXJzID0ge307CiAgICAgICAgbGV0IGpzb247CiAgICAgICAgbGV0IHJlZnJlc2hUb2tlbjsKICAgICAgICBjb25zdCB7YXVkaWVuY2U6IGF1ZGllbmNlLCBzY29wZTogc2NvcGV9ID0gYXV0aCB8fCB7fTsKICAgICAgICB0cnkgewogICAgICAgICAgICBjb25zdCBib2R5ID0gdXNlRm9ybURhdGEgPyBmb3JtRGF0YVRvT2JqZWN0KGZldGNoT3B0aW9ucy5ib2R5KSA6IEpTT04ucGFyc2UoZmV0Y2hPcHRpb25zLmJvZHkpOwogICAgICAgICAgICBpZiAoIWJvZHkucmVmcmVzaF90b2tlbiAmJiBib2R5LmdyYW50X3R5cGUgPT09ICJyZWZyZXNoX3Rva2VuIikgewogICAgICAgICAgICAgICAgcmVmcmVzaFRva2VuID0gZ2V0UmVmcmVzaFRva2VuKGF1ZGllbmNlLCBzY29wZSk7CiAgICAgICAgICAgICAgICBpZiAoIXJlZnJlc2hUb2tlbiAmJiB1c2VNcnJ0KSB7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGF0ZXN0UmVmcmVzaFRva2VuID0gcmVmcmVzaFRva2Vuc1sibGF0ZXN0X3JlZnJlc2hfdG9rZW4iXTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpc0Rvd25zY29waW5nID0gY2hlY2tEb3duc2NvcGluZyhzY29wZSwgYXVkaWVuY2UpOwogICAgICAgICAgICAgICAgICAgIGlmIChsYXRlc3RSZWZyZXNoVG9rZW4gJiYgIWlzRG93bnNjb3BpbmcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFRva2VuID0gbGF0ZXN0UmVmcmVzaFRva2VuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghcmVmcmVzaFRva2VuKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdSZWZyZXNoVG9rZW5FcnJvcihhdWRpZW5jZSwgc2NvcGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZmV0Y2hPcHRpb25zLmJvZHkgPSB1c2VGb3JtRGF0YSA/IGNyZWF0ZVF1ZXJ5UGFyYW1zKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYm9keSksIHsKICAgICAgICAgICAgICAgICAgICByZWZyZXNoX3Rva2VuOiByZWZyZXNoVG9rZW4KICAgICAgICAgICAgICAgIH0pKSA6IEpTT04uc3RyaW5naWZ5KE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYm9keSksIHsKICAgICAgICAgICAgICAgICAgICByZWZyZXNoX3Rva2VuOiByZWZyZXNoVG9rZW4KICAgICAgICAgICAgICAgIH0pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgYWJvcnRDb250cm9sbGVyOwogICAgICAgICAgICBpZiAodHlwZW9mIEFib3J0Q29udHJvbGxlciA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgYWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcjsKICAgICAgICAgICAgICAgIGZldGNoT3B0aW9ucy5zaWduYWwgPSBhYm9ydENvbnRyb2xsZXIuc2lnbmFsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxldCByZXNwb25zZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgUHJvbWlzZS5yYWNlKFsgd2FpdCh0aW1lb3V0KSwgZmV0Y2goZmV0Y2hVcmwsIE9iamVjdC5hc3NpZ24oe30sIGZldGNoT3B0aW9ucykpIF0pOwogICAgICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICAgICAgcG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLm1lc3NhZ2UKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghcmVzcG9uc2UpIHsKICAgICAgICAgICAgICAgIGlmIChhYm9ydENvbnRyb2xsZXIpIGFib3J0Q29udHJvbGxlci5hYm9ydCgpOwogICAgICAgICAgICAgICAgcG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICAgICAgZXJyb3I6ICJUaW1lb3V0IHdoZW4gZXhlY3V0aW5nICdmZXRjaCciCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBoZWFkZXJzID0gZnJvbUVudHJpZXMocmVzcG9uc2UuaGVhZGVycyk7CiAgICAgICAgICAgIGpzb24gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7CiAgICAgICAgICAgIGlmIChqc29uLnJlZnJlc2hfdG9rZW4pIHsKICAgICAgICAgICAgICAgIGlmICh1c2VNcnJ0ICYmIGF1ZGllbmNlICE9PSAiZGVmYXVsdCIpIHsKICAgICAgICAgICAgICAgICAgICByZWZyZXNoVG9rZW5zWyJsYXRlc3RfcmVmcmVzaF90b2tlbiJdID0ganNvbi5yZWZyZXNoX3Rva2VuOwogICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJlZnJlc2hUb2tlbnMocmVmcmVzaFRva2VuLCBqc29uLnJlZnJlc2hfdG9rZW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc2V0UmVmcmVzaFRva2VuKGpzb24ucmVmcmVzaF90b2tlbiwgYXVkaWVuY2UsIHNjb3BlKTsKICAgICAgICAgICAgICAgIGRlbGV0ZSBqc29uLnJlZnJlc2hfdG9rZW47CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkZWxldGVSZWZyZXNoVG9rZW4oYXVkaWVuY2UsIHNjb3BlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgIG9rOiByZXNwb25zZS5vaywKICAgICAgICAgICAgICAgIGpzb246IGpzb24sCiAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzCiAgICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgICAgIHBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICAgICAgb2s6IGZhbHNlLAogICAgICAgICAgICAgICAganNvbjogewogICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvci5lcnJvciwKICAgICAgICAgICAgICAgICAgICBlcnJvcl9kZXNjcmlwdGlvbjogZXJyb3IubWVzc2FnZQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnMKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfTsKICAgIHsKICAgICAgICBhZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwgbWVzc2FnZUhhbmRsZXIpOwogICAgfQp9KSgpOwoK", null, false);
1745
1789
  const singlePromiseMap = {};
1746
1790
  const singlePromise = (cb, key) => {
1747
1791
  let promise = singlePromiseMap[key];
@@ -1828,6 +1872,30 @@
1828
1872
  });
1829
1873
  return result;
1830
1874
  };
1875
+ const allScopesAreIncluded = (scopeToInclude, scopes) => {
1876
+ const scopeGroup = (scopes === null || scopes === void 0 ? void 0 : scopes.split(" ")) || [];
1877
+ const scopesToInclude = (scopeToInclude === null || scopeToInclude === void 0 ? void 0 : scopeToInclude.split(" ")) || [];
1878
+ return scopesToInclude.every((key => scopeGroup.includes(key)));
1879
+ };
1880
+ const getScopeToRequest = (useMrrt, authorizationParams, cachedAudience, cachedScope) => {
1881
+ var _a;
1882
+ if (useMrrt && cachedAudience && cachedScope) {
1883
+ if (authorizationParams.audience !== cachedAudience) {
1884
+ return authorizationParams.scope;
1885
+ }
1886
+ const cachedScopes = cachedScope.split(" ");
1887
+ const newScopes = ((_a = authorizationParams.scope) === null || _a === void 0 ? void 0 : _a.split(" ")) || [];
1888
+ const newScopesAreIncluded = newScopes.every((scope => cachedScopes.includes(scope)));
1889
+ return cachedScopes.length >= newScopes.length && newScopesAreIncluded ? cachedScope : authorizationParams.scope;
1890
+ }
1891
+ return authorizationParams.scope;
1892
+ };
1893
+ const isRefreshWithMrrt = (cachedAudience, cachedScope, requestAudience, requestScope) => {
1894
+ if (cachedAudience !== requestAudience) {
1895
+ return true;
1896
+ }
1897
+ return !allScopesAreIncluded(requestScope, cachedScope);
1898
+ };
1831
1899
  const VERSION = 1;
1832
1900
  const NAME = "auth0-spa-js";
1833
1901
  const TABLES = {
@@ -1955,8 +2023,8 @@
1955
2023
  }
1956
2024
  throw new TypeError("`url` must be absolute or `baseUrl` non-empty.");
1957
2025
  }
1958
- getAccessToken() {
1959
- return this.config.getAccessToken ? this.config.getAccessToken() : this.hooks.getAccessToken();
2026
+ getAccessToken(authParams) {
2027
+ return this.config.getAccessToken ? this.config.getAccessToken(authParams) : this.hooks.getAccessToken(authParams);
1960
2028
  }
1961
2029
  buildBaseRequest(info, init) {
1962
2030
  const request = new Request(info, init);
@@ -1981,8 +2049,8 @@
1981
2049
  });
1982
2050
  request.headers.set("dpop", dpopProof);
1983
2051
  }
1984
- async prepareRequest(request) {
1985
- const accessToken = await this.getAccessToken();
2052
+ async prepareRequest(request, authParams) {
2053
+ const accessToken = await this.getAccessToken(authParams);
1986
2054
  this.setAuthorizationHeader(request, accessToken);
1987
2055
  await this.setDpopProofHeader(request, accessToken);
1988
2056
  }
@@ -2015,19 +2083,19 @@
2015
2083
  }
2016
2084
  return callbacks.onUseDpopNonceError();
2017
2085
  }
2018
- async internalFetchWithAuth(info, init, callbacks) {
2086
+ async internalFetchWithAuth(info, init, callbacks, authParams) {
2019
2087
  const request = this.buildBaseRequest(info, init);
2020
- await this.prepareRequest(request);
2088
+ await this.prepareRequest(request, authParams);
2021
2089
  const response = await this.config.fetch(request);
2022
2090
  return this.handleResponse(response, callbacks);
2023
2091
  }
2024
- fetchWithAuth(info, init) {
2092
+ fetchWithAuth(info, init, authParams) {
2025
2093
  const callbacks = {
2026
2094
  onUseDpopNonceError: () => this.internalFetchWithAuth(info, init, Object.assign(Object.assign({}, callbacks), {
2027
2095
  onUseDpopNonceError: undefined
2028
- }))
2096
+ }), authParams)
2029
2097
  };
2030
- return this.internalFetchWithAuth(info, init, callbacks);
2098
+ return this.internalFetchWithAuth(info, init, callbacks, authParams);
2031
2099
  }
2032
2100
  }
2033
2101
  const lock = new Lock;
@@ -2266,7 +2334,8 @@
2266
2334
  const entry = await this._getEntryFromCache({
2267
2335
  scope: getTokenOptions.authorizationParams.scope,
2268
2336
  audience: getTokenOptions.authorizationParams.audience || "default",
2269
- clientId: this.options.clientId
2337
+ clientId: this.options.clientId,
2338
+ cacheMode: cacheMode
2270
2339
  });
2271
2340
  if (entry) {
2272
2341
  return entry;
@@ -2320,7 +2389,7 @@
2320
2389
  scope: localOptions.authorizationParams.scope,
2321
2390
  audience: localOptions.authorizationParams.audience || "default",
2322
2391
  clientId: this.options.clientId
2323
- }));
2392
+ }), undefined, this.options.useMrrt);
2324
2393
  return cache.access_token;
2325
2394
  }
2326
2395
  async isAuthenticated() {
@@ -2418,7 +2487,7 @@
2418
2487
  scope: options.authorizationParams.scope,
2419
2488
  audience: options.authorizationParams.audience || "default",
2420
2489
  clientId: this.options.clientId
2421
- }));
2490
+ }), undefined, this.options.useMrrt);
2422
2491
  if ((!cache || !cache.refresh_token) && !this.worker) {
2423
2492
  if (this.options.useRefreshTokensFallback) {
2424
2493
  return await this._getTokenFromIFrame(options);
@@ -2427,6 +2496,7 @@
2427
2496
  }
2428
2497
  const redirect_uri = options.authorizationParams.redirect_uri || this.options.authorizationParams.redirect_uri || window.location.origin;
2429
2498
  const timeout = typeof options.timeoutInSeconds === "number" ? options.timeoutInSeconds * 1e3 : null;
2499
+ const scopesToRequest = getScopeToRequest(this.options.useMrrt, options.authorizationParams, cache === null || cache === void 0 ? void 0 : cache.audience, cache === null || cache === void 0 ? void 0 : cache.scope);
2430
2500
  try {
2431
2501
  const tokenResult = await this._requestToken(Object.assign(Object.assign(Object.assign({}, options.authorizationParams), {
2432
2502
  grant_type: "refresh_token",
@@ -2434,7 +2504,24 @@
2434
2504
  redirect_uri: redirect_uri
2435
2505
  }), timeout && {
2436
2506
  timeout: timeout
2437
- }));
2507
+ }), {
2508
+ scopesToRequest: scopesToRequest
2509
+ });
2510
+ if (tokenResult.refresh_token && this.options.useMrrt && (cache === null || cache === void 0 ? void 0 : cache.refresh_token)) {
2511
+ await this.cacheManager.updateEntry(cache.refresh_token, tokenResult.refresh_token);
2512
+ }
2513
+ if (this.options.useMrrt) {
2514
+ const isRefreshMrrt = isRefreshWithMrrt(cache === null || cache === void 0 ? void 0 : cache.audience, cache === null || cache === void 0 ? void 0 : cache.scope, options.authorizationParams.audience, options.authorizationParams.scope);
2515
+ if (isRefreshMrrt) {
2516
+ const tokenHasAllScopes = allScopesAreIncluded(scopesToRequest, tokenResult.scope);
2517
+ if (!tokenHasAllScopes) {
2518
+ if (this.options.useRefreshTokensFallback) {
2519
+ return await this._getTokenFromIFrame(options);
2520
+ }
2521
+ throw new MissingRefreshTokenError(options.authorizationParams.audience || "default", options.authorizationParams.scope);
2522
+ }
2523
+ }
2524
+ }
2438
2525
  return Object.assign(Object.assign({}, tokenResult), {
2439
2526
  scope: options.authorizationParams.scope,
2440
2527
  oauthTokenScope: tokenResult.scope,
@@ -2470,12 +2557,12 @@
2470
2557
  this.userCache.set(CACHE_KEY_ID_TOKEN_SUFFIX, cache);
2471
2558
  return cache;
2472
2559
  }
2473
- async _getEntryFromCache({scope: scope, audience: audience, clientId: clientId}) {
2560
+ async _getEntryFromCache({scope: scope, audience: audience, clientId: clientId, cacheMode: cacheMode}) {
2474
2561
  const entry = await this.cacheManager.get(new CacheKey({
2475
2562
  scope: scope,
2476
2563
  audience: audience,
2477
2564
  clientId: clientId
2478
- }), 60);
2565
+ }), 60, this.options.useMrrt, cacheMode);
2479
2566
  if (entry && entry.access_token) {
2480
2567
  const {token_type: token_type, access_token: access_token, oauthTokenScope: oauthTokenScope, expires_in: expires_in} = entry;
2481
2568
  const cache = await this._getIdTokenFromCache();
@@ -2491,15 +2578,18 @@
2491
2578
  }
2492
2579
  }
2493
2580
  async _requestToken(options, additionalParameters) {
2494
- const {nonceIn: nonceIn, organization: organization} = additionalParameters || {};
2495
- const authResult = await oauthToken(Object.assign({
2581
+ const {nonceIn: nonceIn, organization: organization, scopesToRequest: scopesToRequest} = additionalParameters || {};
2582
+ const authResult = await oauthToken(Object.assign(Object.assign({
2496
2583
  baseUrl: this.domainUrl,
2497
2584
  client_id: this.options.clientId,
2498
2585
  auth0Client: this.options.auth0Client,
2499
2586
  useFormData: this.options.useFormData,
2500
2587
  timeout: this.httpTimeoutMs,
2588
+ useMrrt: this.options.useMrrt,
2501
2589
  dpop: this.dpop
2502
- }, options), this.worker);
2590
+ }, options), {
2591
+ scope: scopesToRequest || options.scope
2592
+ }), this.worker);
2503
2593
  const decodedToken = await this._verifyIdToken(authResult.id_token, nonceIn, organization);
2504
2594
  await this._saveEntryInCache(Object.assign(Object.assign(Object.assign(Object.assign({}, authResult), {
2505
2595
  decodedToken: decodedToken,
@@ -2551,7 +2641,15 @@
2551
2641
  }
2552
2642
  return new Fetcher(config, {
2553
2643
  isDpopEnabled: () => !!this.options.useDpop,
2554
- getAccessToken: () => this.getTokenSilently(),
2644
+ getAccessToken: authParams => {
2645
+ var _a;
2646
+ return this.getTokenSilently({
2647
+ authorizationParams: {
2648
+ scope: (_a = authParams === null || authParams === void 0 ? void 0 : authParams.scope) === null || _a === void 0 ? void 0 : _a.join(" "),
2649
+ audience: authParams === null || authParams === void 0 ? void 0 : authParams.audience
2650
+ }
2651
+ });
2652
+ },
2555
2653
  getDpopNonce: () => this.getDpopNonce(config.dpopNonceId),
2556
2654
  setDpopNonce: nonce => this.setDpopNonce(nonce),
2557
2655
  generateDpopProof: params => this.generateDpopProof(params)