@auth0/auth0-spa-js 2.6.0 → 2.8.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.
Files changed (36) hide show
  1. package/README.md +4 -3
  2. package/dist/auth0-spa-js.development.js +147 -47
  3. package/dist/auth0-spa-js.development.js.map +1 -1
  4. package/dist/auth0-spa-js.production.esm.js +1 -1
  5. package/dist/auth0-spa-js.production.esm.js.map +1 -1
  6. package/dist/auth0-spa-js.production.js +1 -1
  7. package/dist/auth0-spa-js.production.js.map +1 -1
  8. package/dist/auth0-spa-js.worker.development.js +1 -1
  9. package/dist/auth0-spa-js.worker.development.js.map +1 -1
  10. package/dist/auth0-spa-js.worker.production.js +1 -1
  11. package/dist/auth0-spa-js.worker.production.js.map +1 -1
  12. package/dist/lib/auth0-spa-js.cjs.js +157 -47
  13. package/dist/lib/auth0-spa-js.cjs.js.map +1 -1
  14. package/dist/typings/Auth0Client.d.ts +2 -1
  15. package/dist/typings/Auth0Client.utils.d.ts +15 -3
  16. package/dist/typings/cache/cache-manager.d.ts +1 -0
  17. package/dist/typings/constants.d.ts +1 -0
  18. package/dist/typings/errors.d.ts +8 -0
  19. package/dist/typings/fetcher.d.ts +5 -3
  20. package/dist/typings/global.d.ts +9 -1
  21. package/dist/typings/scope.d.ts +25 -0
  22. package/dist/typings/utils.d.ts +6 -0
  23. package/dist/typings/version.d.ts +1 -1
  24. package/package.json +1 -1
  25. package/src/Auth0Client.ts +87 -53
  26. package/src/Auth0Client.utils.ts +28 -5
  27. package/src/api.ts +5 -6
  28. package/src/cache/cache-manager.ts +14 -0
  29. package/src/constants.ts +2 -0
  30. package/src/errors.ts +15 -0
  31. package/src/fetcher.ts +51 -16
  32. package/src/global.ts +11 -1
  33. package/src/scope.ts +57 -0
  34. package/src/utils.ts +36 -0
  35. package/src/version.ts +1 -1
  36. package/src/worker/token.worker.ts +1 -1
@@ -550,7 +550,7 @@ var browserTabsLock = createCommonjsModule((function(module, exports) {
550
550
 
551
551
  var Lock = unwrapExports(browserTabsLock);
552
552
 
553
- var version = "2.6.0";
553
+ var version = "2.8.0";
554
554
 
555
555
  const DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS = 60;
556
556
 
@@ -581,6 +581,8 @@ const DEFAULT_AUTH0_CLIENT = {
581
581
 
582
582
  const DEFAULT_NOW_PROVIDER = () => Date.now();
583
583
 
584
+ const DEFAULT_AUDIENCE = "default";
585
+
584
586
  class GenericError extends Error {
585
587
  constructor(error, error_description) {
586
588
  super(error_description);
@@ -652,6 +654,15 @@ class MissingRefreshTokenError extends GenericError {
652
654
  }
653
655
  }
654
656
 
657
+ class MissingScopesError extends GenericError {
658
+ constructor(audience, scope) {
659
+ super("missing_scopes", `Missing requested scopes after refresh (audience: '${valueOrEmptyString(audience, [ "default" ])}', missing scope: '${valueOrEmptyString(scope)}')`);
660
+ this.audience = audience;
661
+ this.scope = scope;
662
+ Object.setPrototypeOf(this, MissingScopesError.prototype);
663
+ }
664
+ }
665
+
655
666
  class UseDpopNonceError extends GenericError {
656
667
  constructor(newDpopNonce) {
657
668
  super("use_dpop_nonce", "Server rejected DPoP proof: wrong nonce");
@@ -766,6 +777,25 @@ const stripUndefined = params => Object.keys(params).filter((k => typeof params[
766
777
  [key]: params[key]
767
778
  })), {});
768
779
 
780
+ const ALLOWED_AUTH0CLIENT_PROPERTIES = [ {
781
+ key: "name",
782
+ type: [ "string" ]
783
+ }, {
784
+ key: "version",
785
+ type: [ "string", "number" ]
786
+ }, {
787
+ key: "env",
788
+ type: [ "object" ]
789
+ } ];
790
+
791
+ const stripAuth0Client = auth0Client => Object.keys(auth0Client).reduce(((acc, key) => {
792
+ const allowedProperty = ALLOWED_AUTH0CLIENT_PROPERTIES.find((p => p.key === key));
793
+ if (allowedProperty && allowedProperty.type.includes(typeof auth0Client[key])) {
794
+ acc[key] = auth0Client[key];
795
+ }
796
+ return acc;
797
+ }), {});
798
+
769
799
  const createQueryParams = _a => {
770
800
  var {clientId: client_id} = _a, params = __rest(_a, [ "clientId" ]);
771
801
  return new URLSearchParams(stripUndefined(Object.assign({
@@ -1297,12 +1327,12 @@ async function oauthToken(_a, worker) {
1297
1327
  });
1298
1328
  const body = useFormData ? createQueryParams(allParams) : JSON.stringify(allParams);
1299
1329
  const isDpopSupported = isGrantTypeSupported(options.grant_type);
1300
- return await getJSON(`${baseUrl}/oauth/token`, timeout, audience || "default", scope, {
1330
+ return await getJSON(`${baseUrl}/oauth/token`, timeout, audience || DEFAULT_AUDIENCE, scope, {
1301
1331
  method: "POST",
1302
1332
  body: body,
1303
1333
  headers: {
1304
1334
  "Content-Type": useFormData ? "application/x-www-form-urlencoded" : "application/json",
1305
- "Auth0-Client": btoa(JSON.stringify(auth0Client || DEFAULT_AUTH0_CLIENT))
1335
+ "Auth0-Client": btoa(JSON.stringify(stripAuth0Client(auth0Client || DEFAULT_AUTH0_CLIENT)))
1306
1336
  }
1307
1337
  }, worker, useFormData, useMrrt, isDpopSupported ? dpop : undefined);
1308
1338
  }
@@ -1311,6 +1341,33 @@ const dedupe = arr => Array.from(new Set(arr));
1311
1341
 
1312
1342
  const getUniqueScopes = (...scopes) => dedupe(scopes.filter(Boolean).join(" ").trim().split(/\s+/)).join(" ");
1313
1343
 
1344
+ const injectDefaultScopes = (authScopes, openIdScope, ...extraScopes) => {
1345
+ if (typeof authScopes !== "object") {
1346
+ return {
1347
+ [DEFAULT_AUDIENCE]: getUniqueScopes(openIdScope, authScopes, ...extraScopes)
1348
+ };
1349
+ }
1350
+ let requestedScopes = {
1351
+ [DEFAULT_AUDIENCE]: getUniqueScopes(openIdScope, ...extraScopes)
1352
+ };
1353
+ Object.keys(authScopes).forEach((key => {
1354
+ const audienceScopes = authScopes[key];
1355
+ requestedScopes[key] = getUniqueScopes(openIdScope, audienceScopes, ...extraScopes);
1356
+ }));
1357
+ return requestedScopes;
1358
+ };
1359
+
1360
+ const scopesToRequest = (authScopes, methodScopes, audience) => {
1361
+ let scope;
1362
+ if (audience) {
1363
+ scope = authScopes[audience];
1364
+ }
1365
+ if (!scope) {
1366
+ scope = authScopes[DEFAULT_AUDIENCE];
1367
+ }
1368
+ return getUniqueScopes(scope, methodScopes);
1369
+ };
1370
+
1314
1371
  const CACHE_KEY_PREFIX = "@@auth0spajs@@";
1315
1372
 
1316
1373
  const CACHE_KEY_ID_TOKEN_SUFFIX = "@@user@@";
@@ -1485,6 +1542,14 @@ class CacheManager {
1485
1542
  await this.cache.set(cacheKey.toKey(), wrappedEntry);
1486
1543
  await ((_a = this.keyManifest) === null || _a === void 0 ? void 0 : _a.add(cacheKey.toKey()));
1487
1544
  }
1545
+ async remove(client_id, audience, scope) {
1546
+ const cacheKey = new CacheKey({
1547
+ clientId: client_id,
1548
+ scope: scope,
1549
+ audience: audience
1550
+ });
1551
+ await this.cache.remove(cacheKey.toKey());
1552
+ }
1488
1553
  async clear(clientId) {
1489
1554
  var _a;
1490
1555
  const keys = await this.getCacheKeys();
@@ -1925,7 +1990,7 @@ function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
1925
1990
  };
1926
1991
  }
1927
1992
 
1928
- var WorkerFactory = createBase64WorkerFactory("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24oKSB7CiAgICAidXNlIHN0cmljdCI7CiAgICBjbGFzcyBHZW5lcmljRXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgICAgICAgY29uc3RydWN0b3IoZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uKSB7CiAgICAgICAgICAgIHN1cGVyKGVycm9yX2Rlc2NyaXB0aW9uKTsKICAgICAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yOwogICAgICAgICAgICB0aGlzLmVycm9yX2Rlc2NyaXB0aW9uID0gZXJyb3JfZGVzY3JpcHRpb247CiAgICAgICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBHZW5lcmljRXJyb3IucHJvdG90eXBlKTsKICAgICAgICB9CiAgICAgICAgc3RhdGljIGZyb21QYXlsb2FkKHtlcnJvcjogZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uOiBlcnJvcl9kZXNjcmlwdGlvbn0pIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmljRXJyb3IoZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uKTsKICAgICAgICB9CiAgICB9CiAgICBjbGFzcyBNaXNzaW5nUmVmcmVzaFRva2VuRXJyb3IgZXh0ZW5kcyBHZW5lcmljRXJyb3IgewogICAgICAgIGNvbnN0cnVjdG9yKGF1ZGllbmNlLCBzY29wZSkgewogICAgICAgICAgICBzdXBlcigibWlzc2luZ19yZWZyZXNoX3Rva2VuIiwgYE1pc3NpbmcgUmVmcmVzaCBUb2tlbiAoYXVkaWVuY2U6ICcke3ZhbHVlT3JFbXB0eVN0cmluZyhhdWRpZW5jZSwgWyAiZGVmYXVsdCIgXSl9Jywgc2NvcGU6ICcke3ZhbHVlT3JFbXB0eVN0cmluZyhzY29wZSl9JylgKTsKICAgICAgICAgICAgdGhpcy5hdWRpZW5jZSA9IGF1ZGllbmNlOwogICAgICAgICAgICB0aGlzLnNjb3BlID0gc2NvcGU7CiAgICAgICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBNaXNzaW5nUmVmcmVzaFRva2VuRXJyb3IucHJvdG90eXBlKTsKICAgICAgICB9CiAgICB9CiAgICBmdW5jdGlvbiB2YWx1ZU9yRW1wdHlTdHJpbmcodmFsdWUsIGV4Y2x1ZGUgPSBbXSkgewogICAgICAgIHJldHVybiB2YWx1ZSAmJiAhZXhjbHVkZS5pbmNsdWRlcyh2YWx1ZSkgPyB2YWx1ZSA6ICIiOwogICAgfQogICAgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHsKICAgICAgICB2YXIgdCA9IHt9OwogICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKSB0W3BdID0gc1twXTsKICAgICAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSAiZnVuY3Rpb24iKSBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSkgdFtwW2ldXSA9IHNbcFtpXV07CiAgICAgICAgfQogICAgICAgIHJldHVybiB0OwogICAgfQogICAgdHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gImZ1bmN0aW9uIiA/IFN1cHByZXNzZWRFcnJvciA6IGZ1bmN0aW9uKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7CiAgICAgICAgdmFyIGUgPSBuZXcgRXJyb3IobWVzc2FnZSk7CiAgICAgICAgcmV0dXJuIGUubmFtZSA9ICJTdXBwcmVzc2VkRXJyb3IiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7CiAgICB9OwogICAgY29uc3Qgc3RyaXBVbmRlZmluZWQgPSBwYXJhbXMgPT4gT2JqZWN0LmtleXMocGFyYW1zKS5maWx0ZXIoKGsgPT4gdHlwZW9mIHBhcmFtc1trXSAhPT0gInVuZGVmaW5lZCIpKS5yZWR1Y2UoKChhY2MsIGtleSkgPT4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBhY2MpLCB7CiAgICAgICAgW2tleV06IHBhcmFtc1trZXldCiAgICB9KSksIHt9KTsKICAgIGNvbnN0IGNyZWF0ZVF1ZXJ5UGFyYW1zID0gX2EgPT4gewogICAgICAgIHZhciB7Y2xpZW50SWQ6IGNsaWVudF9pZH0gPSBfYSwgcGFyYW1zID0gX19yZXN0KF9hLCBbICJjbGllbnRJZCIgXSk7CiAgICAgICAgcmV0dXJuIG5ldyBVUkxTZWFyY2hQYXJhbXMoc3RyaXBVbmRlZmluZWQoT2JqZWN0LmFzc2lnbih7CiAgICAgICAgICAgIGNsaWVudF9pZDogY2xpZW50X2lkCiAgICAgICAgfSwgcGFyYW1zKSkpLnRvU3RyaW5nKCk7CiAgICB9OwogICAgY29uc3QgZnJvbUVudHJpZXMgPSBpdGVyYWJsZSA9PiBbIC4uLml0ZXJhYmxlIF0ucmVkdWNlKCgob2JqLCBba2V5LCB2YWxdKSA9PiB7CiAgICAgICAgb2JqW2tleV0gPSB2YWw7CiAgICAgICAgcmV0dXJuIG9iajsKICAgIH0pLCB7fSk7CiAgICBsZXQgcmVmcmVzaFRva2VucyA9IHt9OwogICAgY29uc3QgY2FjaGVLZXkgPSAoYXVkaWVuY2UsIHNjb3BlKSA9PiBgJHthdWRpZW5jZX18JHtzY29wZX1gOwogICAgY29uc3QgY2FjaGVLZXlDb250YWluc0F1ZGllbmNlID0gKGF1ZGllbmNlLCBjYWNoZUtleSkgPT4gY2FjaGVLZXkuc3RhcnRzV2l0aChgJHthdWRpZW5jZX18YCk7CiAgICBjb25zdCBnZXRSZWZyZXNoVG9rZW4gPSAoYXVkaWVuY2UsIHNjb3BlKSA9PiByZWZyZXNoVG9rZW5zW2NhY2hlS2V5KGF1ZGllbmNlLCBzY29wZSldOwogICAgY29uc3Qgc2V0UmVmcmVzaFRva2VuID0gKHJlZnJlc2hUb2tlbiwgYXVkaWVuY2UsIHNjb3BlKSA9PiByZWZyZXNoVG9rZW5zW2NhY2hlS2V5KGF1ZGllbmNlLCBzY29wZSldID0gcmVmcmVzaFRva2VuOwogICAgY29uc3QgZGVsZXRlUmVmcmVzaFRva2VuID0gKGF1ZGllbmNlLCBzY29wZSkgPT4gZGVsZXRlIHJlZnJlc2hUb2tlbnNbY2FjaGVLZXkoYXVkaWVuY2UsIHNjb3BlKV07CiAgICBjb25zdCB3YWl0ID0gdGltZSA9PiBuZXcgUHJvbWlzZSgocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIHRpbWUpKSk7CiAgICBjb25zdCBmb3JtRGF0YVRvT2JqZWN0ID0gZm9ybURhdGEgPT4gewogICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhmb3JtRGF0YSk7CiAgICAgICAgY29uc3QgcGFyc2VkUXVlcnkgPSB7fTsKICAgICAgICBxdWVyeVBhcmFtcy5mb3JFYWNoKCgodmFsLCBrZXkpID0+IHsKICAgICAgICAgICAgcGFyc2VkUXVlcnlba2V5XSA9IHZhbDsKICAgICAgICB9KSk7CiAgICAgICAgcmV0dXJuIHBhcnNlZFF1ZXJ5OwogICAgfTsKICAgIGNvbnN0IHVwZGF0ZVJlZnJlc2hUb2tlbnMgPSAob2xkUmVmcmVzaFRva2VuLCBuZXdSZWZyZXNoVG9rZW4pID0+IHsKICAgICAgICBPYmplY3QuZW50cmllcyhyZWZyZXNoVG9rZW5zKS5mb3JFYWNoKCgoW2tleSwgdG9rZW5dKSA9PiB7CiAgICAgICAgICAgIGlmICh0b2tlbiA9PT0gb2xkUmVmcmVzaFRva2VuKSB7CiAgICAgICAgICAgICAgICByZWZyZXNoVG9rZW5zW2tleV0gPSBuZXdSZWZyZXNoVG9rZW47CiAgICAgICAgICAgIH0KICAgICAgICB9KSk7CiAgICB9OwogICAgY29uc3QgY2hlY2tEb3duc2NvcGluZyA9IChzY29wZSwgYXVkaWVuY2UpID0+IHsKICAgICAgICBjb25zdCBmaW5kQ29pbmNpZGVuY2UgPSBPYmplY3Qua2V5cyhyZWZyZXNoVG9rZW5zKS5maW5kKChrZXkgPT4gewogICAgICAgICAgICBpZiAoa2V5ICE9PSAibGF0ZXN0X3JlZnJlc2hfdG9rZW4iKSB7CiAgICAgICAgICAgICAgICBjb25zdCBpc1NhbWVBdWRpZW5jZSA9IGNhY2hlS2V5Q29udGFpbnNBdWRpZW5jZShhdWRpZW5jZSwga2V5KTsKICAgICAgICAgICAgICAgIGNvbnN0IHNjb3Blc0tleSA9IGtleS5zcGxpdCgifCIpWzFdLnNwbGl0KCIgIik7CiAgICAgICAgICAgICAgICBjb25zdCByZXF1ZXN0ZWRTY29wZXMgPSBzY29wZS5zcGxpdCgiICIpOwogICAgICAgICAgICAgICAgY29uc3Qgc2NvcGVzQXJlSW5jbHVkZWQgPSByZXF1ZXN0ZWRTY29wZXMuZXZlcnkoKGtleSA9PiBzY29wZXNLZXkuaW5jbHVkZXMoa2V5KSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIGlzU2FtZUF1ZGllbmNlICYmIHNjb3Blc0FyZUluY2x1ZGVkOwogICAgICAgICAgICB9CiAgICAgICAgfSkpOwogICAgICAgIHJldHVybiBmaW5kQ29pbmNpZGVuY2UgPyB0cnVlIDogZmFsc2U7CiAgICB9OwogICAgY29uc3QgbWVzc2FnZUhhbmRsZXIgPSBhc3luYyAoe2RhdGE6IHt0aW1lb3V0OiB0aW1lb3V0LCBhdXRoOiBhdXRoLCBmZXRjaFVybDogZmV0Y2hVcmwsIGZldGNoT3B0aW9uczogZmV0Y2hPcHRpb25zLCB1c2VGb3JtRGF0YTogdXNlRm9ybURhdGEsIHVzZU1ycnQ6IHVzZU1ycnR9LCBwb3J0czogW3BvcnRdfSkgPT4gewogICAgICAgIGxldCBoZWFkZXJzID0ge307CiAgICAgICAgbGV0IGpzb247CiAgICAgICAgbGV0IHJlZnJlc2hUb2tlbjsKICAgICAgICBjb25zdCB7YXVkaWVuY2U6IGF1ZGllbmNlLCBzY29wZTogc2NvcGV9ID0gYXV0aCB8fCB7fTsKICAgICAgICB0cnkgewogICAgICAgICAgICBjb25zdCBib2R5ID0gdXNlRm9ybURhdGEgPyBmb3JtRGF0YVRvT2JqZWN0KGZldGNoT3B0aW9ucy5ib2R5KSA6IEpTT04ucGFyc2UoZmV0Y2hPcHRpb25zLmJvZHkpOwogICAgICAgICAgICBpZiAoIWJvZHkucmVmcmVzaF90b2tlbiAmJiBib2R5LmdyYW50X3R5cGUgPT09ICJyZWZyZXNoX3Rva2VuIikgewogICAgICAgICAgICAgICAgcmVmcmVzaFRva2VuID0gZ2V0UmVmcmVzaFRva2VuKGF1ZGllbmNlLCBzY29wZSk7CiAgICAgICAgICAgICAgICBpZiAoIXJlZnJlc2hUb2tlbiAmJiB1c2VNcnJ0KSB7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGF0ZXN0UmVmcmVzaFRva2VuID0gcmVmcmVzaFRva2Vuc1sibGF0ZXN0X3JlZnJlc2hfdG9rZW4iXTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpc0Rvd25zY29waW5nID0gY2hlY2tEb3duc2NvcGluZyhzY29wZSwgYXVkaWVuY2UpOwogICAgICAgICAgICAgICAgICAgIGlmIChsYXRlc3RSZWZyZXNoVG9rZW4gJiYgIWlzRG93bnNjb3BpbmcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFRva2VuID0gbGF0ZXN0UmVmcmVzaFRva2VuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghcmVmcmVzaFRva2VuKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdSZWZyZXNoVG9rZW5FcnJvcihhdWRpZW5jZSwgc2NvcGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZmV0Y2hPcHRpb25zLmJvZHkgPSB1c2VGb3JtRGF0YSA/IGNyZWF0ZVF1ZXJ5UGFyYW1zKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYm9keSksIHsKICAgICAgICAgICAgICAgICAgICByZWZyZXNoX3Rva2VuOiByZWZyZXNoVG9rZW4KICAgICAgICAgICAgICAgIH0pKSA6IEpTT04uc3RyaW5naWZ5KE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYm9keSksIHsKICAgICAgICAgICAgICAgICAgICByZWZyZXNoX3Rva2VuOiByZWZyZXNoVG9rZW4KICAgICAgICAgICAgICAgIH0pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgYWJvcnRDb250cm9sbGVyOwogICAgICAgICAgICBpZiAodHlwZW9mIEFib3J0Q29udHJvbGxlciA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgYWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcjsKICAgICAgICAgICAgICAgIGZldGNoT3B0aW9ucy5zaWduYWwgPSBhYm9ydENvbnRyb2xsZXIuc2lnbmFsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxldCByZXNwb25zZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgUHJvbWlzZS5yYWNlKFsgd2FpdCh0aW1lb3V0KSwgZmV0Y2goZmV0Y2hVcmwsIE9iamVjdC5hc3NpZ24oe30sIGZldGNoT3B0aW9ucykpIF0pOwogICAgICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICAgICAgcG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLm1lc3NhZ2UKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghcmVzcG9uc2UpIHsKICAgICAgICAgICAgICAgIGlmIChhYm9ydENvbnRyb2xsZXIpIGFib3J0Q29udHJvbGxlci5hYm9ydCgpOwogICAgICAgICAgICAgICAgcG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICAgICAgZXJyb3I6ICJUaW1lb3V0IHdoZW4gZXhlY3V0aW5nICdmZXRjaCciCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBoZWFkZXJzID0gZnJvbUVudHJpZXMocmVzcG9uc2UuaGVhZGVycyk7CiAgICAgICAgICAgIGpzb24gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7CiAgICAgICAgICAgIGlmIChqc29uLnJlZnJlc2hfdG9rZW4pIHsKICAgICAgICAgICAgICAgIGlmICh1c2VNcnJ0ICYmIGF1ZGllbmNlICE9PSAiZGVmYXVsdCIpIHsKICAgICAgICAgICAgICAgICAgICByZWZyZXNoVG9rZW5zWyJsYXRlc3RfcmVmcmVzaF90b2tlbiJdID0ganNvbi5yZWZyZXNoX3Rva2VuOwogICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJlZnJlc2hUb2tlbnMocmVmcmVzaFRva2VuLCBqc29uLnJlZnJlc2hfdG9rZW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc2V0UmVmcmVzaFRva2VuKGpzb24ucmVmcmVzaF90b2tlbiwgYXVkaWVuY2UsIHNjb3BlKTsKICAgICAgICAgICAgICAgIGRlbGV0ZSBqc29uLnJlZnJlc2hfdG9rZW47CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkZWxldGVSZWZyZXNoVG9rZW4oYXVkaWVuY2UsIHNjb3BlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgIG9rOiByZXNwb25zZS5vaywKICAgICAgICAgICAgICAgIGpzb246IGpzb24sCiAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzCiAgICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgICAgIHBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICAgICAgb2s6IGZhbHNlLAogICAgICAgICAgICAgICAganNvbjogewogICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvci5lcnJvciwKICAgICAgICAgICAgICAgICAgICBlcnJvcl9kZXNjcmlwdGlvbjogZXJyb3IubWVzc2FnZQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnMKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfTsKICAgIHsKICAgICAgICBhZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwgbWVzc2FnZUhhbmRsZXIpOwogICAgfQp9KSgpOwoK", null, false);
1993
+ var WorkerFactory = createBase64WorkerFactory("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24oKSB7CiAgICAidXNlIHN0cmljdCI7CiAgICBjbGFzcyBHZW5lcmljRXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgICAgICAgY29uc3RydWN0b3IoZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uKSB7CiAgICAgICAgICAgIHN1cGVyKGVycm9yX2Rlc2NyaXB0aW9uKTsKICAgICAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yOwogICAgICAgICAgICB0aGlzLmVycm9yX2Rlc2NyaXB0aW9uID0gZXJyb3JfZGVzY3JpcHRpb247CiAgICAgICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBHZW5lcmljRXJyb3IucHJvdG90eXBlKTsKICAgICAgICB9CiAgICAgICAgc3RhdGljIGZyb21QYXlsb2FkKHtlcnJvcjogZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uOiBlcnJvcl9kZXNjcmlwdGlvbn0pIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmljRXJyb3IoZXJyb3IsIGVycm9yX2Rlc2NyaXB0aW9uKTsKICAgICAgICB9CiAgICB9CiAgICBjbGFzcyBNaXNzaW5nUmVmcmVzaFRva2VuRXJyb3IgZXh0ZW5kcyBHZW5lcmljRXJyb3IgewogICAgICAgIGNvbnN0cnVjdG9yKGF1ZGllbmNlLCBzY29wZSkgewogICAgICAgICAgICBzdXBlcigibWlzc2luZ19yZWZyZXNoX3Rva2VuIiwgYE1pc3NpbmcgUmVmcmVzaCBUb2tlbiAoYXVkaWVuY2U6ICcke3ZhbHVlT3JFbXB0eVN0cmluZyhhdWRpZW5jZSwgWyAiZGVmYXVsdCIgXSl9Jywgc2NvcGU6ICcke3ZhbHVlT3JFbXB0eVN0cmluZyhzY29wZSl9JylgKTsKICAgICAgICAgICAgdGhpcy5hdWRpZW5jZSA9IGF1ZGllbmNlOwogICAgICAgICAgICB0aGlzLnNjb3BlID0gc2NvcGU7CiAgICAgICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBNaXNzaW5nUmVmcmVzaFRva2VuRXJyb3IucHJvdG90eXBlKTsKICAgICAgICB9CiAgICB9CiAgICBmdW5jdGlvbiB2YWx1ZU9yRW1wdHlTdHJpbmcodmFsdWUsIGV4Y2x1ZGUgPSBbXSkgewogICAgICAgIHJldHVybiB2YWx1ZSAmJiAhZXhjbHVkZS5pbmNsdWRlcyh2YWx1ZSkgPyB2YWx1ZSA6ICIiOwogICAgfQogICAgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHsKICAgICAgICB2YXIgdCA9IHt9OwogICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKSB0W3BdID0gc1twXTsKICAgICAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSAiZnVuY3Rpb24iKSBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSkgdFtwW2ldXSA9IHNbcFtpXV07CiAgICAgICAgfQogICAgICAgIHJldHVybiB0OwogICAgfQogICAgdHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gImZ1bmN0aW9uIiA/IFN1cHByZXNzZWRFcnJvciA6IGZ1bmN0aW9uKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7CiAgICAgICAgdmFyIGUgPSBuZXcgRXJyb3IobWVzc2FnZSk7CiAgICAgICAgcmV0dXJuIGUubmFtZSA9ICJTdXBwcmVzc2VkRXJyb3IiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7CiAgICB9OwogICAgY29uc3Qgc3RyaXBVbmRlZmluZWQgPSBwYXJhbXMgPT4gT2JqZWN0LmtleXMocGFyYW1zKS5maWx0ZXIoKGsgPT4gdHlwZW9mIHBhcmFtc1trXSAhPT0gInVuZGVmaW5lZCIpKS5yZWR1Y2UoKChhY2MsIGtleSkgPT4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBhY2MpLCB7CiAgICAgICAgW2tleV06IHBhcmFtc1trZXldCiAgICB9KSksIHt9KTsKICAgIGNvbnN0IGNyZWF0ZVF1ZXJ5UGFyYW1zID0gX2EgPT4gewogICAgICAgIHZhciB7Y2xpZW50SWQ6IGNsaWVudF9pZH0gPSBfYSwgcGFyYW1zID0gX19yZXN0KF9hLCBbICJjbGllbnRJZCIgXSk7CiAgICAgICAgcmV0dXJuIG5ldyBVUkxTZWFyY2hQYXJhbXMoc3RyaXBVbmRlZmluZWQoT2JqZWN0LmFzc2lnbih7CiAgICAgICAgICAgIGNsaWVudF9pZDogY2xpZW50X2lkCiAgICAgICAgfSwgcGFyYW1zKSkpLnRvU3RyaW5nKCk7CiAgICB9OwogICAgY29uc3QgZnJvbUVudHJpZXMgPSBpdGVyYWJsZSA9PiBbIC4uLml0ZXJhYmxlIF0ucmVkdWNlKCgob2JqLCBba2V5LCB2YWxdKSA9PiB7CiAgICAgICAgb2JqW2tleV0gPSB2YWw7CiAgICAgICAgcmV0dXJuIG9iajsKICAgIH0pLCB7fSk7CiAgICBsZXQgcmVmcmVzaFRva2VucyA9IHt9OwogICAgY29uc3QgY2FjaGVLZXkgPSAoYXVkaWVuY2UsIHNjb3BlKSA9PiBgJHthdWRpZW5jZX18JHtzY29wZX1gOwogICAgY29uc3QgY2FjaGVLZXlDb250YWluc0F1ZGllbmNlID0gKGF1ZGllbmNlLCBjYWNoZUtleSkgPT4gY2FjaGVLZXkuc3RhcnRzV2l0aChgJHthdWRpZW5jZX18YCk7CiAgICBjb25zdCBnZXRSZWZyZXNoVG9rZW4gPSAoYXVkaWVuY2UsIHNjb3BlKSA9PiByZWZyZXNoVG9rZW5zW2NhY2hlS2V5KGF1ZGllbmNlLCBzY29wZSldOwogICAgY29uc3Qgc2V0UmVmcmVzaFRva2VuID0gKHJlZnJlc2hUb2tlbiwgYXVkaWVuY2UsIHNjb3BlKSA9PiByZWZyZXNoVG9rZW5zW2NhY2hlS2V5KGF1ZGllbmNlLCBzY29wZSldID0gcmVmcmVzaFRva2VuOwogICAgY29uc3QgZGVsZXRlUmVmcmVzaFRva2VuID0gKGF1ZGllbmNlLCBzY29wZSkgPT4gZGVsZXRlIHJlZnJlc2hUb2tlbnNbY2FjaGVLZXkoYXVkaWVuY2UsIHNjb3BlKV07CiAgICBjb25zdCB3YWl0ID0gdGltZSA9PiBuZXcgUHJvbWlzZSgocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIHRpbWUpKSk7CiAgICBjb25zdCBmb3JtRGF0YVRvT2JqZWN0ID0gZm9ybURhdGEgPT4gewogICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhmb3JtRGF0YSk7CiAgICAgICAgY29uc3QgcGFyc2VkUXVlcnkgPSB7fTsKICAgICAgICBxdWVyeVBhcmFtcy5mb3JFYWNoKCgodmFsLCBrZXkpID0+IHsKICAgICAgICAgICAgcGFyc2VkUXVlcnlba2V5XSA9IHZhbDsKICAgICAgICB9KSk7CiAgICAgICAgcmV0dXJuIHBhcnNlZFF1ZXJ5OwogICAgfTsKICAgIGNvbnN0IHVwZGF0ZVJlZnJlc2hUb2tlbnMgPSAob2xkUmVmcmVzaFRva2VuLCBuZXdSZWZyZXNoVG9rZW4pID0+IHsKICAgICAgICBPYmplY3QuZW50cmllcyhyZWZyZXNoVG9rZW5zKS5mb3JFYWNoKCgoW2tleSwgdG9rZW5dKSA9PiB7CiAgICAgICAgICAgIGlmICh0b2tlbiA9PT0gb2xkUmVmcmVzaFRva2VuKSB7CiAgICAgICAgICAgICAgICByZWZyZXNoVG9rZW5zW2tleV0gPSBuZXdSZWZyZXNoVG9rZW47CiAgICAgICAgICAgIH0KICAgICAgICB9KSk7CiAgICB9OwogICAgY29uc3QgY2hlY2tEb3duc2NvcGluZyA9IChzY29wZSwgYXVkaWVuY2UpID0+IHsKICAgICAgICBjb25zdCBmaW5kQ29pbmNpZGVuY2UgPSBPYmplY3Qua2V5cyhyZWZyZXNoVG9rZW5zKS5maW5kKChrZXkgPT4gewogICAgICAgICAgICBpZiAoa2V5ICE9PSAibGF0ZXN0X3JlZnJlc2hfdG9rZW4iKSB7CiAgICAgICAgICAgICAgICBjb25zdCBpc1NhbWVBdWRpZW5jZSA9IGNhY2hlS2V5Q29udGFpbnNBdWRpZW5jZShhdWRpZW5jZSwga2V5KTsKICAgICAgICAgICAgICAgIGNvbnN0IHNjb3Blc0tleSA9IGtleS5zcGxpdCgifCIpWzFdLnNwbGl0KCIgIik7CiAgICAgICAgICAgICAgICBjb25zdCByZXF1ZXN0ZWRTY29wZXMgPSBzY29wZS5zcGxpdCgiICIpOwogICAgICAgICAgICAgICAgY29uc3Qgc2NvcGVzQXJlSW5jbHVkZWQgPSByZXF1ZXN0ZWRTY29wZXMuZXZlcnkoKGtleSA9PiBzY29wZXNLZXkuaW5jbHVkZXMoa2V5KSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIGlzU2FtZUF1ZGllbmNlICYmIHNjb3Blc0FyZUluY2x1ZGVkOwogICAgICAgICAgICB9CiAgICAgICAgfSkpOwogICAgICAgIHJldHVybiBmaW5kQ29pbmNpZGVuY2UgPyB0cnVlIDogZmFsc2U7CiAgICB9OwogICAgY29uc3QgbWVzc2FnZUhhbmRsZXIgPSBhc3luYyAoe2RhdGE6IHt0aW1lb3V0OiB0aW1lb3V0LCBhdXRoOiBhdXRoLCBmZXRjaFVybDogZmV0Y2hVcmwsIGZldGNoT3B0aW9uczogZmV0Y2hPcHRpb25zLCB1c2VGb3JtRGF0YTogdXNlRm9ybURhdGEsIHVzZU1ycnQ6IHVzZU1ycnR9LCBwb3J0czogW3BvcnRdfSkgPT4gewogICAgICAgIGxldCBoZWFkZXJzID0ge307CiAgICAgICAgbGV0IGpzb247CiAgICAgICAgbGV0IHJlZnJlc2hUb2tlbjsKICAgICAgICBjb25zdCB7YXVkaWVuY2U6IGF1ZGllbmNlLCBzY29wZTogc2NvcGV9ID0gYXV0aCB8fCB7fTsKICAgICAgICB0cnkgewogICAgICAgICAgICBjb25zdCBib2R5ID0gdXNlRm9ybURhdGEgPyBmb3JtRGF0YVRvT2JqZWN0KGZldGNoT3B0aW9ucy5ib2R5KSA6IEpTT04ucGFyc2UoZmV0Y2hPcHRpb25zLmJvZHkpOwogICAgICAgICAgICBpZiAoIWJvZHkucmVmcmVzaF90b2tlbiAmJiBib2R5LmdyYW50X3R5cGUgPT09ICJyZWZyZXNoX3Rva2VuIikgewogICAgICAgICAgICAgICAgcmVmcmVzaFRva2VuID0gZ2V0UmVmcmVzaFRva2VuKGF1ZGllbmNlLCBzY29wZSk7CiAgICAgICAgICAgICAgICBpZiAoIXJlZnJlc2hUb2tlbiAmJiB1c2VNcnJ0KSB7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGF0ZXN0UmVmcmVzaFRva2VuID0gcmVmcmVzaFRva2Vuc1sibGF0ZXN0X3JlZnJlc2hfdG9rZW4iXTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpc0Rvd25zY29waW5nID0gY2hlY2tEb3duc2NvcGluZyhzY29wZSwgYXVkaWVuY2UpOwogICAgICAgICAgICAgICAgICAgIGlmIChsYXRlc3RSZWZyZXNoVG9rZW4gJiYgIWlzRG93bnNjb3BpbmcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFRva2VuID0gbGF0ZXN0UmVmcmVzaFRva2VuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghcmVmcmVzaFRva2VuKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE1pc3NpbmdSZWZyZXNoVG9rZW5FcnJvcihhdWRpZW5jZSwgc2NvcGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZmV0Y2hPcHRpb25zLmJvZHkgPSB1c2VGb3JtRGF0YSA/IGNyZWF0ZVF1ZXJ5UGFyYW1zKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYm9keSksIHsKICAgICAgICAgICAgICAgICAgICByZWZyZXNoX3Rva2VuOiByZWZyZXNoVG9rZW4KICAgICAgICAgICAgICAgIH0pKSA6IEpTT04uc3RyaW5naWZ5KE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYm9keSksIHsKICAgICAgICAgICAgICAgICAgICByZWZyZXNoX3Rva2VuOiByZWZyZXNoVG9rZW4KICAgICAgICAgICAgICAgIH0pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgYWJvcnRDb250cm9sbGVyOwogICAgICAgICAgICBpZiAodHlwZW9mIEFib3J0Q29udHJvbGxlciA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgYWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcjsKICAgICAgICAgICAgICAgIGZldGNoT3B0aW9ucy5zaWduYWwgPSBhYm9ydENvbnRyb2xsZXIuc2lnbmFsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxldCByZXNwb25zZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgUHJvbWlzZS5yYWNlKFsgd2FpdCh0aW1lb3V0KSwgZmV0Y2goZmV0Y2hVcmwsIE9iamVjdC5hc3NpZ24oe30sIGZldGNoT3B0aW9ucykpIF0pOwogICAgICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICAgICAgcG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLm1lc3NhZ2UKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghcmVzcG9uc2UpIHsKICAgICAgICAgICAgICAgIGlmIChhYm9ydENvbnRyb2xsZXIpIGFib3J0Q29udHJvbGxlci5hYm9ydCgpOwogICAgICAgICAgICAgICAgcG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICAgICAgZXJyb3I6ICJUaW1lb3V0IHdoZW4gZXhlY3V0aW5nICdmZXRjaCciCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBoZWFkZXJzID0gZnJvbUVudHJpZXMocmVzcG9uc2UuaGVhZGVycyk7CiAgICAgICAgICAgIGpzb24gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7CiAgICAgICAgICAgIGlmIChqc29uLnJlZnJlc2hfdG9rZW4pIHsKICAgICAgICAgICAgICAgIGlmICh1c2VNcnJ0KSB7CiAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFRva2Vuc1sibGF0ZXN0X3JlZnJlc2hfdG9rZW4iXSA9IGpzb24ucmVmcmVzaF90b2tlbjsKICAgICAgICAgICAgICAgICAgICB1cGRhdGVSZWZyZXNoVG9rZW5zKHJlZnJlc2hUb2tlbiwganNvbi5yZWZyZXNoX3Rva2VuKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNldFJlZnJlc2hUb2tlbihqc29uLnJlZnJlc2hfdG9rZW4sIGF1ZGllbmNlLCBzY29wZSk7CiAgICAgICAgICAgICAgICBkZWxldGUganNvbi5yZWZyZXNoX3Rva2VuOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZGVsZXRlUmVmcmVzaFRva2VuKGF1ZGllbmNlLCBzY29wZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICBvazogcmVzcG9uc2Uub2ssCiAgICAgICAgICAgICAgICBqc29uOiBqc29uLAogICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVycwogICAgICAgICAgICB9KTsKICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICBwb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgIG9rOiBmYWxzZSwKICAgICAgICAgICAgICAgIGpzb246IHsKICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IuZXJyb3IsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JfZGVzY3JpcHRpb246IGVycm9yLm1lc3NhZ2UKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH07CiAgICB7CiAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsIG1lc3NhZ2VIYW5kbGVyKTsKICAgIH0KfSkoKTsKCg==", null, false);
1929
1994
 
1930
1995
  const singlePromiseMap = {};
1931
1996
 
@@ -1990,6 +2055,8 @@ class CacheKeyManifest {
1990
2055
 
1991
2056
  const GET_TOKEN_SILENTLY_LOCK_KEY = "auth0.lock.getTokenSilently";
1992
2057
 
2058
+ const buildGetTokenSilentlyLockKey = (clientId, audience) => `${GET_TOKEN_SILENTLY_LOCK_KEY}.${clientId}.${audience}`;
2059
+
1993
2060
  const buildOrganizationHintCookieName = clientId => `auth0.${clientId}.organization_hint`;
1994
2061
 
1995
2062
  const OLD_IS_AUTHENTICATED_COOKIE_NAME = "auth0.is.authenticated";
@@ -2006,7 +2073,7 @@ const cacheFactory = location => cacheLocationBuilders[location];
2006
2073
  const getAuthorizeParams = (clientOptions, scope, authorizationParams, state, nonce, code_challenge, redirect_uri, response_mode, thumbprint) => Object.assign(Object.assign(Object.assign({
2007
2074
  client_id: clientOptions.clientId
2008
2075
  }, clientOptions.authorizationParams), authorizationParams), {
2009
- scope: getUniqueScopes(scope, authorizationParams.scope),
2076
+ scope: scopesToRequest(scope, authorizationParams.scope, authorizationParams.audience),
2010
2077
  response_type: "code",
2011
2078
  response_mode: response_mode || "query",
2012
2079
  state: state,
@@ -2031,6 +2098,13 @@ const allScopesAreIncluded = (scopeToInclude, scopes) => {
2031
2098
  return scopesToInclude.every((key => scopeGroup.includes(key)));
2032
2099
  };
2033
2100
 
2101
+ const getMissingScopes = (requestedScope, respondedScope) => {
2102
+ const requestedScopes = (requestedScope === null || requestedScope === void 0 ? void 0 : requestedScope.split(" ")) || [];
2103
+ const respondedScopes = (respondedScope === null || respondedScope === void 0 ? void 0 : respondedScope.split(" ")) || [];
2104
+ const missingScopes = requestedScopes.filter((scope => respondedScopes.indexOf(scope) == -1));
2105
+ return missingScopes.join(",");
2106
+ };
2107
+
2034
2108
  const getScopeToRequest = (useMrrt, authorizationParams, cachedAudience, cachedScope) => {
2035
2109
  var _a;
2036
2110
  if (useMrrt && cachedAudience && cachedScope) {
@@ -2164,6 +2238,13 @@ class Dpop {
2164
2238
  }
2165
2239
  }
2166
2240
 
2241
+ var TokenType;
2242
+
2243
+ (function(TokenType) {
2244
+ TokenType["Bearer"] = "Bearer";
2245
+ TokenType["DPoP"] = "DPoP";
2246
+ })(TokenType || (TokenType = {}));
2247
+
2167
2248
  class Fetcher {
2168
2249
  constructor(config, hooks) {
2169
2250
  this.hooks = hooks;
@@ -2188,15 +2269,25 @@ class Fetcher {
2188
2269
  getAccessToken(authParams) {
2189
2270
  return this.config.getAccessToken ? this.config.getAccessToken(authParams) : this.hooks.getAccessToken(authParams);
2190
2271
  }
2272
+ extractUrl(info) {
2273
+ if (typeof info === "string") {
2274
+ return info;
2275
+ }
2276
+ if (info instanceof URL) {
2277
+ return info.href;
2278
+ }
2279
+ return info.url;
2280
+ }
2191
2281
  buildBaseRequest(info, init) {
2192
- const request = new Request(info, init);
2193
2282
  if (!this.config.baseUrl) {
2194
- return request;
2283
+ return new Request(info, init);
2195
2284
  }
2196
- return new Request(this.buildUrl(this.config.baseUrl, request.url), request);
2285
+ const finalUrl = this.buildUrl(this.config.baseUrl, this.extractUrl(info));
2286
+ const finalInfo = info instanceof Request ? new Request(finalUrl, info) : finalUrl;
2287
+ return new Request(finalInfo, init);
2197
2288
  }
2198
- setAuthorizationHeader(request, accessToken) {
2199
- request.headers.set("authorization", `${this.config.dpopNonceId ? "DPoP" : "Bearer"} ${accessToken}`);
2289
+ setAuthorizationHeader(request, accessToken, tokenType = TokenType.Bearer) {
2290
+ request.headers.set("authorization", `${tokenType} ${accessToken}`);
2200
2291
  }
2201
2292
  async setDpopProofHeader(request, accessToken) {
2202
2293
  if (!this.config.dpopNonceId) {
@@ -2212,9 +2303,20 @@ class Fetcher {
2212
2303
  request.headers.set("dpop", dpopProof);
2213
2304
  }
2214
2305
  async prepareRequest(request, authParams) {
2215
- const accessToken = await this.getAccessToken(authParams);
2216
- this.setAuthorizationHeader(request, accessToken);
2217
- await this.setDpopProofHeader(request, accessToken);
2306
+ const accessTokenResponse = await this.getAccessToken(authParams);
2307
+ let tokenType;
2308
+ let accessToken;
2309
+ if (typeof accessTokenResponse === "string") {
2310
+ tokenType = this.config.dpopNonceId ? TokenType.DPoP : TokenType.Bearer;
2311
+ accessToken = accessTokenResponse;
2312
+ } else {
2313
+ tokenType = accessTokenResponse.token_type;
2314
+ accessToken = accessTokenResponse.access_token;
2315
+ }
2316
+ this.setAuthorizationHeader(request, accessToken, tokenType);
2317
+ if (tokenType === TokenType.DPoP) {
2318
+ await this.setDpopProofHeader(request, accessToken);
2319
+ }
2218
2320
  }
2219
2321
  getHeader(headers, name) {
2220
2322
  if (Array.isArray(headers)) {
@@ -2230,7 +2332,7 @@ class Fetcher {
2230
2332
  return false;
2231
2333
  }
2232
2334
  const wwwAuthHeader = this.getHeader(response.headers, "www-authenticate");
2233
- return wwwAuthHeader.includes("use_dpop_nonce");
2335
+ return wwwAuthHeader.includes("invalid_dpop_nonce") || wwwAuthHeader.includes("use_dpop_nonce");
2234
2336
  }
2235
2337
  async handleResponse(response, callbacks) {
2236
2338
  const newDpopNonce = this.getHeader(response.headers, DPOP_NONCE_HEADER);
@@ -2325,6 +2427,7 @@ const lock = new Lock;
2325
2427
  class Auth0Client {
2326
2428
  constructor(options) {
2327
2429
  this.userCache = (new InMemoryCache).enclosedCache;
2430
+ this.activeLockKeys = new Set;
2328
2431
  this.defaultOptions = {
2329
2432
  authorizationParams: {
2330
2433
  scope: DEFAULT_SCOPE
@@ -2333,7 +2436,11 @@ class Auth0Client {
2333
2436
  useFormData: true
2334
2437
  };
2335
2438
  this._releaseLockOnPageHide = async () => {
2336
- await lock.releaseLock(GET_TOKEN_SILENTLY_LOCK_KEY);
2439
+ const lockKeysToRelease = Array.from(this.activeLockKeys);
2440
+ for (const lockKey of lockKeysToRelease) {
2441
+ await lock.releaseLock(lockKey);
2442
+ }
2443
+ this.activeLockKeys.clear();
2337
2444
  window.removeEventListener("pagehide", this._releaseLockOnPageHide);
2338
2445
  };
2339
2446
  this.options = Object.assign(Object.assign(Object.assign({}, this.defaultOptions), options), {
@@ -2360,7 +2467,7 @@ class Auth0Client {
2360
2467
  this.isAuthenticatedCookieName = buildIsAuthenticatedCookieName(this.options.clientId);
2361
2468
  this.sessionCheckExpiryDays = options.sessionCheckExpiryDays || DEFAULT_SESSION_CHECK_EXPIRY_DAYS;
2362
2469
  const transactionStorage = options.useCookiesForTransactions ? this.cookieStorage : SessionStorage;
2363
- this.scope = getUniqueScopes("openid", this.options.authorizationParams.scope, this.options.useRefreshTokens ? "offline_access" : "");
2470
+ this.scope = injectDefaultScopes(this.options.authorizationParams.scope, "openid", this.options.useRefreshTokens ? "offline_access" : "");
2364
2471
  this.transactionManager = new TransactionManager(transactionStorage, this.options.clientId, this.options.cookieDomain);
2365
2472
  this.nowProvider = this.options.nowProvider || DEFAULT_NOW_PROVIDER;
2366
2473
  this.cacheManager = new CacheManager(cache, !cache.allKeys ? new CacheKeyManifest(cache, this.options.clientId) : undefined, this.nowProvider);
@@ -2375,7 +2482,8 @@ class Auth0Client {
2375
2482
  authorizationParams: {
2376
2483
  scope: "create:me:connected_accounts",
2377
2484
  audience: myAccountApiIdentifier
2378
- }
2485
+ },
2486
+ detailedResponse: true
2379
2487
  })
2380
2488
  }));
2381
2489
  this.myAccountApi = new MyAccountApiClient(myAccountFetcher, myAccountApiIdentifier);
@@ -2433,7 +2541,7 @@ class Auth0Client {
2433
2541
  nonce: nonce,
2434
2542
  code_verifier: code_verifier,
2435
2543
  scope: params.scope,
2436
- audience: params.audience || "default",
2544
+ audience: params.audience || DEFAULT_AUDIENCE,
2437
2545
  redirect_uri: params.redirect_uri,
2438
2546
  state: state,
2439
2547
  url: url
@@ -2583,12 +2691,12 @@ class Auth0Client {
2583
2691
  } catch (_) {}
2584
2692
  }
2585
2693
  async getTokenSilently(options = {}) {
2586
- var _a;
2694
+ var _a, _b;
2587
2695
  const localOptions = Object.assign(Object.assign({
2588
2696
  cacheMode: "on"
2589
2697
  }, options), {
2590
2698
  authorizationParams: Object.assign(Object.assign(Object.assign({}, this.options.authorizationParams), options.authorizationParams), {
2591
- scope: getUniqueScopes(this.scope, (_a = options.authorizationParams) === null || _a === void 0 ? void 0 : _a.scope)
2699
+ scope: scopesToRequest(this.scope, (_a = options.authorizationParams) === null || _a === void 0 ? void 0 : _a.scope, ((_b = options.authorizationParams) === null || _b === void 0 ? void 0 : _b.audience) || this.options.authorizationParams.audience)
2592
2700
  })
2593
2701
  });
2594
2702
  const result = await singlePromise((() => this._getTokenSilently(localOptions)), `${this.options.clientId}::${localOptions.authorizationParams.audience}::${localOptions.authorizationParams.scope}`);
@@ -2599,7 +2707,7 @@ class Auth0Client {
2599
2707
  if (cacheMode !== "off") {
2600
2708
  const entry = await this._getEntryFromCache({
2601
2709
  scope: getTokenOptions.authorizationParams.scope,
2602
- audience: getTokenOptions.authorizationParams.audience || "default",
2710
+ audience: getTokenOptions.authorizationParams.audience || DEFAULT_AUDIENCE,
2603
2711
  clientId: this.options.clientId,
2604
2712
  cacheMode: cacheMode
2605
2713
  });
@@ -2610,13 +2718,17 @@ class Auth0Client {
2610
2718
  if (cacheMode === "cache-only") {
2611
2719
  return;
2612
2720
  }
2613
- if (await retryPromise((() => lock.acquireLock(GET_TOKEN_SILENTLY_LOCK_KEY, 5e3)), 10)) {
2614
- try {
2721
+ const lockKey = buildGetTokenSilentlyLockKey(this.options.clientId, getTokenOptions.authorizationParams.audience || "default");
2722
+ if (await retryPromise((() => lock.acquireLock(lockKey, 5e3)), 10)) {
2723
+ this.activeLockKeys.add(lockKey);
2724
+ if (this.activeLockKeys.size === 1) {
2615
2725
  window.addEventListener("pagehide", this._releaseLockOnPageHide);
2726
+ }
2727
+ try {
2616
2728
  if (cacheMode !== "off") {
2617
2729
  const entry = await this._getEntryFromCache({
2618
2730
  scope: getTokenOptions.authorizationParams.scope,
2619
- audience: getTokenOptions.authorizationParams.audience || "default",
2731
+ audience: getTokenOptions.authorizationParams.audience || DEFAULT_AUDIENCE,
2620
2732
  clientId: this.options.clientId
2621
2733
  });
2622
2734
  if (entry) {
@@ -2635,25 +2747,28 @@ class Auth0Client {
2635
2747
  expires_in: expires_in
2636
2748
  });
2637
2749
  } finally {
2638
- await lock.releaseLock(GET_TOKEN_SILENTLY_LOCK_KEY);
2639
- window.removeEventListener("pagehide", this._releaseLockOnPageHide);
2750
+ await lock.releaseLock(lockKey);
2751
+ this.activeLockKeys.delete(lockKey);
2752
+ if (this.activeLockKeys.size === 0) {
2753
+ window.removeEventListener("pagehide", this._releaseLockOnPageHide);
2754
+ }
2640
2755
  }
2641
2756
  } else {
2642
2757
  throw new TimeoutError;
2643
2758
  }
2644
2759
  }
2645
2760
  async getTokenWithPopup(options = {}, config = {}) {
2646
- var _a;
2761
+ var _a, _b;
2647
2762
  const localOptions = Object.assign(Object.assign({}, options), {
2648
2763
  authorizationParams: Object.assign(Object.assign(Object.assign({}, this.options.authorizationParams), options.authorizationParams), {
2649
- scope: getUniqueScopes(this.scope, (_a = options.authorizationParams) === null || _a === void 0 ? void 0 : _a.scope)
2764
+ scope: scopesToRequest(this.scope, (_a = options.authorizationParams) === null || _a === void 0 ? void 0 : _a.scope, ((_b = options.authorizationParams) === null || _b === void 0 ? void 0 : _b.audience) || this.options.authorizationParams.audience)
2650
2765
  })
2651
2766
  });
2652
2767
  config = Object.assign(Object.assign({}, DEFAULT_POPUP_CONFIG_OPTIONS), config);
2653
2768
  await this.loginWithPopup(localOptions, config);
2654
2769
  const cache = await this.cacheManager.get(new CacheKey({
2655
2770
  scope: localOptions.authorizationParams.scope,
2656
- audience: localOptions.authorizationParams.audience || "default",
2771
+ audience: localOptions.authorizationParams.audience || DEFAULT_AUDIENCE,
2657
2772
  clientId: this.options.clientId
2658
2773
  }), undefined, this.options.useMrrt);
2659
2774
  return cache.access_token;
@@ -2751,14 +2866,14 @@ class Auth0Client {
2751
2866
  async _getTokenUsingRefreshToken(options) {
2752
2867
  const cache = await this.cacheManager.get(new CacheKey({
2753
2868
  scope: options.authorizationParams.scope,
2754
- audience: options.authorizationParams.audience || "default",
2869
+ audience: options.authorizationParams.audience || DEFAULT_AUDIENCE,
2755
2870
  clientId: this.options.clientId
2756
2871
  }), undefined, this.options.useMrrt);
2757
2872
  if ((!cache || !cache.refresh_token) && !this.worker) {
2758
2873
  if (this.options.useRefreshTokensFallback) {
2759
2874
  return await this._getTokenFromIFrame(options);
2760
2875
  }
2761
- throw new MissingRefreshTokenError(options.authorizationParams.audience || "default", options.authorizationParams.scope);
2876
+ throw new MissingRefreshTokenError(options.authorizationParams.audience || DEFAULT_AUDIENCE, options.authorizationParams.scope);
2762
2877
  }
2763
2878
  const redirect_uri = options.authorizationParams.redirect_uri || this.options.authorizationParams.redirect_uri || window.location.origin;
2764
2879
  const timeout = typeof options.timeoutInSeconds === "number" ? options.timeoutInSeconds * 1e3 : null;
@@ -2784,14 +2899,16 @@ class Auth0Client {
2784
2899
  if (this.options.useRefreshTokensFallback) {
2785
2900
  return await this._getTokenFromIFrame(options);
2786
2901
  }
2787
- throw new MissingRefreshTokenError(options.authorizationParams.audience || "default", options.authorizationParams.scope);
2902
+ await this.cacheManager.remove(this.options.clientId, options.authorizationParams.audience, options.authorizationParams.scope);
2903
+ const missingScopes = getMissingScopes(scopesToRequest, tokenResult.scope);
2904
+ throw new MissingScopesError(options.authorizationParams.audience || "default", missingScopes);
2788
2905
  }
2789
2906
  }
2790
2907
  }
2791
2908
  return Object.assign(Object.assign({}, tokenResult), {
2792
2909
  scope: options.authorizationParams.scope,
2793
2910
  oauthTokenScope: tokenResult.scope,
2794
- audience: options.authorizationParams.audience || "default"
2911
+ audience: options.authorizationParams.audience || DEFAULT_AUDIENCE
2795
2912
  });
2796
2913
  } catch (e) {
2797
2914
  if ((e.message.indexOf(MISSING_REFRESH_TOKEN_ERROR_MESSAGE) > -1 || e.message && e.message.indexOf(INVALID_REFRESH_TOKEN_ERROR_MESSAGE) > -1) && this.options.useRefreshTokensFallback) {
@@ -2810,11 +2927,12 @@ class Auth0Client {
2810
2927
  await this.cacheManager.set(entryWithoutIdToken);
2811
2928
  }
2812
2929
  async _getIdTokenFromCache() {
2813
- const audience = this.options.authorizationParams.audience || "default";
2930
+ const audience = this.options.authorizationParams.audience || DEFAULT_AUDIENCE;
2931
+ const scope = this.scope[audience];
2814
2932
  const cache = await this.cacheManager.getIdToken(new CacheKey({
2815
2933
  clientId: this.options.clientId,
2816
2934
  audience: audience,
2817
- scope: this.scope
2935
+ scope: scope
2818
2936
  }));
2819
2937
  const currentCache = this.userCache.get(CACHE_KEY_ID_TOKEN_SUFFIX);
2820
2938
  if (cache && cache.id_token === (currentCache === null || currentCache === void 0 ? void 0 : currentCache.id_token)) {
@@ -2860,7 +2978,7 @@ class Auth0Client {
2860
2978
  await this._saveEntryInCache(Object.assign(Object.assign(Object.assign(Object.assign({}, authResult), {
2861
2979
  decodedToken: decodedToken,
2862
2980
  scope: options.scope,
2863
- audience: options.audience || "default"
2981
+ audience: options.audience || DEFAULT_AUDIENCE
2864
2982
  }), authResult.scope ? {
2865
2983
  oauthTokenScope: authResult.scope
2866
2984
  } : null), {
@@ -2880,7 +2998,7 @@ class Auth0Client {
2880
2998
  grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
2881
2999
  subject_token: options.subject_token,
2882
3000
  subject_token_type: options.subject_token_type,
2883
- scope: getUniqueScopes(options.scope, this.scope),
3001
+ scope: scopesToRequest(this.scope, options.scope, options.audience || this.options.authorizationParams.audience),
2884
3002
  audience: options.audience || this.options.authorizationParams.audience
2885
3003
  });
2886
3004
  }
@@ -2902,9 +3020,6 @@ class Auth0Client {
2902
3020
  return this.dpop.generateProof(params);
2903
3021
  }
2904
3022
  createFetcher(config = {}) {
2905
- if (this.options.useDpop && !config.dpopNonceId) {
2906
- throw new TypeError("When `useDpop` is enabled, `dpopNonceId` must be set when calling `createFetcher()`.");
2907
- }
2908
3023
  return new Fetcher(config, {
2909
3024
  isDpopEnabled: () => !!this.options.useDpop,
2910
3025
  getAccessToken: authParams => {
@@ -2913,7 +3028,8 @@ class Auth0Client {
2913
3028
  authorizationParams: {
2914
3029
  scope: (_a = authParams === null || authParams === void 0 ? void 0 : authParams.scope) === null || _a === void 0 ? void 0 : _a.join(" "),
2915
3030
  audience: authParams === null || authParams === void 0 ? void 0 : authParams.audience
2916
- }
3031
+ },
3032
+ detailedResponse: true
2917
3033
  });
2918
3034
  },
2919
3035
  getDpopNonce: () => this.getDpopNonce(config.dpopNonceId),
@@ -2922,12 +3038,6 @@ class Auth0Client {
2922
3038
  });
2923
3039
  }
2924
3040
  async connectAccountWithRedirect(options) {
2925
- if (!this.options.useDpop) {
2926
- throw new Error("`useDpop` option must be enabled before using connectAccountWithRedirect.");
2927
- }
2928
- if (!this.options.useMrrt) {
2929
- throw new Error("`useMrrt` option must be enabled before using connectAccountWithRedirect.");
2930
- }
2931
3041
  const {openUrl: openUrl, appState: appState, connection: connection, authorization_params: authorization_params, redirectUri: redirectUri = this.options.authorizationParams.redirect_uri || window.location.origin} = options;
2932
3042
  if (!connection) {
2933
3043
  throw new Error("connection is required");