text: import { Constants as Constants$1, ProtocolMode, LogLevel, StringUtils, AccountEntity, CacheManager, IdTokenEntity, AccessTokenEntity, RefreshTokenEntity, AppMetadataEntity, ServerTelemetryEntity, AuthorityMetadataEntity, ThrottlingEntity, TokenCacheContext, Logger, ResponseMode, AuthenticationScheme, AuthorizationCodeClient, AuthError, RefreshTokenClient, SilentFlowClient, UsernamePasswordClient, OIDC_DEFAULT_SCOPES, ServerTelemetryManager, AuthorityFactory, DeviceCodeClient, ClientAuthError, TimeUtils, ClientCredentialClient, OnBehalfOfClient } from '@azure/msal-common';
  export { AuthError, AuthErrorMessage, ClientAuthError, ClientAuthErrorMessage, ClientConfigurationError, ClientConfigurationErrorMessage, InteractionRequiredAuthError, LogLevel, Logger, PromptValue, ProtocolMode, ResponseMode, ServerError, TokenCacheContext } from '@azure/msal-common';
  import axios from 'axios';
  import { v4 } from 'uuid';
  import crypto from 'crypto';
  import { sign } from 'jsonwebtoken';
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  
  /**
   * http methods
   */
  var HttpMethod;
  
  (function (HttpMethod) {
    HttpMethod["GET"] = "get";
    HttpMethod["POST"] = "post";
  })(HttpMethod || (HttpMethod = {}));
  /**
   * Constants used for region discovery
   */
  
  
  const REGION_ENVIRONMENT_VARIABLE = "REGION_NAME";
  /**
   * Constant used for PKCE
   */
  
  const RANDOM_OCTET_SIZE = 32;
  /**
   * Constants used in PKCE
   */
  
  const Hash = {
    SHA256: "sha256"
  };
  /**
   * Constants for encoding schemes
   */
  
  const CharSet = {
    CV_CHARSET: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
  };
  /**
   * Constants
   */
  
  const Constants = {
    MSAL_SKU: "msal.js.node",
    JWT_BEARER_ASSERTION_TYPE: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
  };
  /**
   * API Codes for Telemetry purposes.
   * Before adding a new code you must claim it in the MSAL Telemetry tracker as these number spaces are shared across all MSALs
   * 0-99 Silent Flow
   * 600-699 Device Code Flow
   * 800-899 Auth Code Flow
   */
  
  var ApiId;
  
  (function (ApiId) {
    ApiId[ApiId["acquireTokenSilent"] = 62] = "acquireTokenSilent";
    ApiId[ApiId["acquireTokenByUsernamePassword"] = 371] = "acquireTokenByUsernamePassword";
    ApiId[ApiId["acquireTokenByDeviceCode"] = 671] = "acquireTokenByDeviceCode";
    ApiId[ApiId["acquireTokenByClientCredential"] = 771] = "acquireTokenByClientCredential";
    ApiId[ApiId["acquireTokenByCode"] = 871] = "acquireTokenByCode";
    ApiId[ApiId["acquireTokenByRefreshToken"] = 872] = "acquireTokenByRefreshToken";
  })(ApiId || (ApiId = {}));
  /**
   * JWT  constants
   */
  
  
  const JwtConstants = {
    ALGORITHM: "alg",
    RSA_256: "RS256",
    X5T: "x5t",
    X5C: "x5c",
    AUDIENCE: "aud",
    EXPIRATION_TIME: "exp",
    ISSUER: "iss",
    SUBJECT: "sub",
    NOT_BEFORE: "nbf",
    JWT_ID: "jti"
  };
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  /**
   * This class implements the API for network requests.
   */
  
  class HttpClient {
    /**
     * Http Get request
     * @param url
     * @param options
     */
    async sendGetRequestAsync(url, options) {
      const request = {
        method: HttpMethod.GET,
        url: url,
        headers: options && options.headers,
        validateStatus: () => true
      };
      const response = await axios(request);
      return {
        headers: response.headers,
        body: response.data,
        status: response.status
      };
    }
    /**
     * Http Post request
     * @param url
     * @param options
     */
  
  
    async sendPostRequestAsync(url, options, cancellationToken) {
      const request = {
        method: HttpMethod.POST,
        url: url,
        data: options && options.body || "",
        timeout: cancellationToken,
        headers: options && options.headers,
        validateStatus: () => true
      };
      const response = await axios(request);
      return {
        headers: response.headers,
        body: response.data,
        status: response.status
      };
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  class NetworkUtils {
    /**
     * Returns best compatible network client object.
     */
    static getNetworkClient() {
      return new HttpClient();
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  const DEFAULT_AUTH_OPTIONS = {
    clientId: "",
    authority: Constants$1.DEFAULT_AUTHORITY,
    clientSecret: "",
    clientAssertion: "",
    clientCertificate: {
      thumbprint: "",
      privateKey: "",
      x5c: ""
    },
    knownAuthorities: [],
    cloudDiscoveryMetadata: "",
    authorityMetadata: "",
    clientCapabilities: [],
    protocolMode: ProtocolMode.AAD
  };
  const DEFAULT_CACHE_OPTIONS = {};
  const DEFAULT_LOGGER_OPTIONS = {
    loggerCallback: () => {// allow users to not set logger call back
    },
    piiLoggingEnabled: false,
    logLevel: LogLevel.Info
  };
  const DEFAULT_SYSTEM_OPTIONS = {
    loggerOptions: DEFAULT_LOGGER_OPTIONS,
    networkClient: /*#__PURE__*/NetworkUtils.getNetworkClient()
  };
  /**
   * Sets the default options when not explicitly configured from app developer
   *
   * @param auth - Authentication options
   * @param cache - Cache options
   * @param system - System options
   *
   * @returns Configuration
   * @public
   */
  
  function buildAppConfiguration({
    auth,
    cache,
    system
  }) {
    return {
      auth: { ...DEFAULT_AUTH_OPTIONS,
        ...auth
      },
      cache: { ...DEFAULT_CACHE_OPTIONS,
        ...cache
      },
      system: { ...DEFAULT_SYSTEM_OPTIONS,
        ...system
      }
    };
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  class GuidGenerator {
    /**
     *
     * RFC4122: The version 4 UUID is meant for generating UUIDs from truly-random or pseudo-random numbers.
     * uuidv4 generates guids from cryprtographically-string random
     */
    static generateGuid() {
      return v4();
    }
    /**
     * verifies if a string is  GUID
     * @param guid
     */
  
  
    static isGuid(guid) {
      const regexGuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      return regexGuid.test(guid);
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  class EncodingUtils {
    /**
     * 'utf8': Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8.
     * 'base64': Base64 encoding.
     *
     * @param str text
     */
    static base64Encode(str, encoding) {
      return Buffer.from(str, encoding).toString("base64");
    }
    /**
     * encode a URL
     * @param str
     */
  
  
    static base64EncodeUrl(str, encoding) {
      return EncodingUtils.base64Encode(str, encoding).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
    }
    /**
     * 'utf8': Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8.
     * 'base64': Base64 encoding.
     *
     * @param base64Str Base64 encoded text
     */
  
  
    static base64Decode(base64Str) {
      return Buffer.from(base64Str, "base64").toString("utf8");
    }
    /**
     * @param base64Str Base64 encoded Url
     */
  
  
    static base64DecodeUrl(base64Str) {
      let str = base64Str.replace(/-/g, "+").replace(/_/g, "/");
  
      while (str.length % 4) {
        str += "=";
      }
  
      return EncodingUtils.base64Decode(str);
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  /**
   * https://tools.ietf.org/html/rfc7636#page-8
   */
  
  class PkceGenerator {
    /**
     * generates the codeVerfier and the challenge from the codeVerfier
     * reference: https://tools.ietf.org/html/rfc7636#section-4.1 and https://tools.ietf.org/html/rfc7636#section-4.2
     */
    async generatePkceCodes() {
      const verifier = this.generateCodeVerifier();
      const challenge = this.generateCodeChallengeFromVerifier(verifier);
      return {
        verifier,
        challenge
      };
    }
    /**
     * generates the codeVerfier; reference: https://tools.ietf.org/html/rfc7636#section-4.1
     */
  
  
    generateCodeVerifier() {
      const charArr = [];
      const maxNumber = 256 - 256 % CharSet.CV_CHARSET.length;
  
      while (charArr.length <= RANDOM_OCTET_SIZE) {
        const byte = crypto.randomBytes(1)[0];
  
        if (byte >= maxNumber) {
          /*
           * Ignore this number to maintain randomness.
           * Including it would result in an unequal distribution of characters after doing the modulo
           */
          continue;
        }
  
        const index = byte % CharSet.CV_CHARSET.length;
        charArr.push(CharSet.CV_CHARSET[index]);
      }
  
      const verifier = charArr.join("");
      return EncodingUtils.base64EncodeUrl(verifier);
    }
    /**
     * generate the challenge from the codeVerfier; reference: https://tools.ietf.org/html/rfc7636#section-4.2
     * @param codeVerifier
     */
  
  
    generateCodeChallengeFromVerifier(codeVerifier) {
      return EncodingUtils.base64EncodeUrl(this.sha256(codeVerifier).toString("base64"), "base64");
    }
    /**
     * generate 'SHA256' hash
     * @param buffer
     */
  
  
    sha256(buffer) {
      return crypto.createHash(Hash.SHA256).update(buffer).digest();
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  /**
   * This class implements MSAL node's crypto interface, which allows it to perform base64 encoding and decoding, generating cryptographically random GUIDs and
   * implementing Proof Key for Code Exchange specs for the OAuth Authorization Code Flow using PKCE (rfc here: https://tools.ietf.org/html/rfc7636).
   * @public
   */
  
  class CryptoProvider {
    constructor() {
      // Browser crypto needs to be validated first before any other classes can be set.
      this.pkceGenerator = new PkceGenerator();
    }
    /**
     * Creates a new random GUID - used to populate state and nonce.
     * @returns string (GUID)
     */
  
  
    createNewGuid() {
      return GuidGenerator.generateGuid();
    }
    /**
     * Encodes input string to base64.
     * @param input - string to be encoded
     */
  
  
    base64Encode(input) {
      return EncodingUtils.base64Encode(input);
    }
    /**
     * Decodes input string from base64.
     * @param input - string to be decoded
     */
  
  
    base64Decode(input) {
      return EncodingUtils.base64Decode(input);
    }
    /**
     * Generates PKCE codes used in Authorization Code Flow.
     */
  
  
    generatePkceCodes() {
      return this.pkceGenerator.generatePkceCodes();
    }
    /**
     * Generates a keypair, stores it and returns a thumbprint - not yet implemented for node
     */
  
  
    getPublicKeyThumbprint() {
      throw new Error("Method not implemented.");
    }
    /**
     * Removes cryptographic keypair from key store matching the keyId passed in
     * @param kid
     */
  
  
    removeTokenBindingKey() {
      throw new Error("Method not implemented.");
    }
    /**
     * Removes all cryptographic keys from Keystore
     */
  
  
    clearKeystore() {
      throw new Error("Method not implemented.");
    }
    /**
     * Signs the given object as a jwt payload with private key retrieved by given kid - currently not implemented for node
     */
  
  
    signJwt() {
      throw new Error("Method not implemented.");
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  /**
   * This class deserializes cache entities read from the file into in memory object types defined internally
   */
  
  class Deserializer {
    /**
     * Parse the JSON blob in memory and deserialize the content
     * @param cachedJson
     */
    static deserializeJSONBlob(jsonFile) {
      const deserializedCache = StringUtils.isEmpty(jsonFile) ? {} : JSON.parse(jsonFile);
      return deserializedCache;
    }
    /**
     * Deserializes accounts to AccountEntity objects
     * @param accounts
     */
  
  
    static deserializeAccounts(accounts) {
      const accountObjects = {};
  
      if (accounts) {
        Object.keys(accounts).map(function (key) {
          const serializedAcc = accounts[key];
          const mappedAcc = {
            homeAccountId: serializedAcc.home_account_id,
            environment: serializedAcc.environment,
            realm: serializedAcc.realm,
            localAccountId: serializedAcc.local_account_id,
            username: serializedAcc.username,
            authorityType: serializedAcc.authority_type,
            name: serializedAcc.name,
            clientInfo: serializedAcc.client_info,
            lastModificationTime: serializedAcc.last_modification_time,
            lastModificationApp: serializedAcc.last_modification_app
          };
          const account = new AccountEntity();
          CacheManager.toObject(account, mappedAcc);
          accountObjects[key] = account;
        });
      }
  
      return accountObjects;
    }
    /**
     * Deserializes id tokens to IdTokenEntity objects
     * @param idTokens
     */
  
  
    static deserializeIdTokens(idTokens) {
      const idObjects = {};
  
      if (idTokens) {
        Object.keys(idTokens).map(function (key) {
          const serializedIdT = idTokens[key];
          const mappedIdT = {
            homeAccountId: serializedIdT.home_account_id,
            environment: serializedIdT.environment,
            credentialType: serializedIdT.credential_type,
            clientId: serializedIdT.client_id,
            secret: serializedIdT.secret,
            realm: serializedIdT.realm
          };
          const idToken = new IdTokenEntity();
          CacheManager.toObject(idToken, mappedIdT);
          idObjects[key] = idToken;
        });
      }
  
      return idObjects;
    }
    /**
     * Deserializes access tokens to AccessTokenEntity objects
     * @param accessTokens
     */
  
  
    static deserializeAccessTokens(accessTokens) {
      const atObjects = {};
  
      if (accessTokens) {
        Object.keys(accessTokens).map(function (key) {
          const serializedAT = accessTokens[key];
          const mappedAT = {
            homeAccountId: serializedAT.home_account_id,
            environment: serializedAT.environment,
            credentialType: serializedAT.credential_type,
            clientId: serializedAT.client_id,
            secret: serializedAT.secret,
            realm: serializedAT.realm,
            target: serializedAT.target,
            cachedAt: serializedAT.cached_at,
            expiresOn: serializedAT.expires_on,
            extendedExpiresOn: serializedAT.extended_expires_on,
            refreshOn: serializedAT.refresh_on,
            keyId: serializedAT.key_id,
            tokenType: serializedAT.token_type
          };
          const accessToken = new AccessTokenEntity();
          CacheManager.toObject(accessToken, mappedAT);
          atObjects[key] = accessToken;
        });
      }
  
      return atObjects;
    }
    /**
     * Deserializes refresh tokens to RefreshTokenEntity objects
     * @param refreshTokens
     */
  
  
    static deserializeRefreshTokens(refreshTokens) {
      const rtObjects = {};
  
      if (refreshTokens) {
        Object.keys(refreshTokens).map(function (key) {
          const serializedRT = refreshTokens[key];
          const mappedRT = {
            homeAccountId: serializedRT.home_account_id,
            environment: serializedRT.environment,
            credentialType: serializedRT.credential_type,
            clientId: serializedRT.client_id,
            secret: serializedRT.secret,
            familyId: serializedRT.family_id,
            target: serializedRT.target,
            realm: serializedRT.realm
          };
          const refreshToken = new RefreshTokenEntity();
          CacheManager.toObject(refreshToken, mappedRT);
          rtObjects[key] = refreshToken;
        });
      }
  
      return rtObjects;
    }
    /**
     * Deserializes appMetadata to AppMetaData objects
     * @param appMetadata
     */
  
  
    static deserializeAppMetadata(appMetadata) {
      const appMetadataObjects = {};
  
      if (appMetadata) {
        Object.keys(appMetadata).map(function (key) {
          const serializedAmdt = appMetadata[key];
          const mappedAmd = {
            clientId: serializedAmdt.client_id,
            environment: serializedAmdt.environment,
            familyId: serializedAmdt.family_id
          };
          const amd = new AppMetadataEntity();
          CacheManager.toObject(amd, mappedAmd);
          appMetadataObjects[key] = amd;
        });
      }
  
      return appMetadataObjects;
    }
    /**
     * Deserialize an inMemory Cache
     * @param jsonCache
     */
  
  
    static deserializeAllCache(jsonCache) {
      return {
        accounts: jsonCache.Account ? this.deserializeAccounts(jsonCache.Account) : {},
        idTokens: jsonCache.IdToken ? this.deserializeIdTokens(jsonCache.IdToken) : {},
        accessTokens: jsonCache.AccessToken ? this.deserializeAccessTokens(jsonCache.AccessToken) : {},
        refreshTokens: jsonCache.RefreshToken ? this.deserializeRefreshTokens(jsonCache.RefreshToken) : {},
        appMetadata: jsonCache.AppMetadata ? this.deserializeAppMetadata(jsonCache.AppMetadata) : {}
      };
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  class Serializer {
    /**
     * serialize the JSON blob
     * @param data
     */
    static serializeJSONBlob(data) {
      return JSON.stringify(data);
    }
    /**
     * Serialize Accounts
     * @param accCache
     */
  
  
    static serializeAccounts(accCache) {
      const accounts = {};
      Object.keys(accCache).map(function (key) {
        const accountEntity = accCache[key];
        accounts[key] = {
          home_account_id: accountEntity.homeAccountId,
          environment: accountEntity.environment,
          realm: accountEntity.realm,
          local_account_id: accountEntity.localAccountId,
          username: accountEntity.username,
          authority_type: accountEntity.authorityType,
          name: accountEntity.name,
          client_info: accountEntity.clientInfo,
          last_modification_time: accountEntity.lastModificationTime,
          last_modification_app: accountEntity.lastModificationApp
        };
      });
      return accounts;
    }
    /**
     * Serialize IdTokens
     * @param idTCache
     */
  
  
    static serializeIdTokens(idTCache) {
      const idTokens = {};
      Object.keys(idTCache).map(function (key) {
        const idTEntity = idTCache[key];
        idTokens[key] = {
          home_account_id: idTEntity.homeAccountId,
          environment: idTEntity.environment,
          credential_type: idTEntity.credentialType,
          client_id: idTEntity.clientId,
          secret: idTEntity.secret,
          realm: idTEntity.realm
        };
      });
      return idTokens;
    }
    /**
     * Serializes AccessTokens
     * @param atCache
     */
  
  
    static serializeAccessTokens(atCache) {
      const accessTokens = {};
      Object.keys(atCache).map(function (key) {
        const atEntity = atCache[key];
        accessTokens[key] = {
          home_account_id: atEntity.homeAccountId,
          environment: atEntity.environment,
          credential_type: atEntity.credentialType,
          client_id: atEntity.clientId,
          secret: atEntity.secret,
          realm: atEntity.realm,
          target: atEntity.target,
          cached_at: atEntity.cachedAt,
          expires_on: atEntity.expiresOn,
          extended_expires_on: atEntity.extendedExpiresOn,
          refresh_on: atEntity.refreshOn,
          key_id: atEntity.keyId,
          token_type: atEntity.tokenType
        };
      });
      return accessTokens;
    }
    /**
     * Serialize refreshTokens
     * @param rtCache
     */
  
  
    static serializeRefreshTokens(rtCache) {
      const refreshTokens = {};
      Object.keys(rtCache).map(function (key) {
        const rtEntity = rtCache[key];
        refreshTokens[key] = {
          home_account_id: rtEntity.homeAccountId,
          environment: rtEntity.environment,
          credential_type: rtEntity.credentialType,
          client_id: rtEntity.clientId,
          secret: rtEntity.secret,
          family_id: rtEntity.familyId,
          target: rtEntity.target,
          realm: rtEntity.realm
        };
      });
      return refreshTokens;
    }
    /**
     * Serialize amdtCache
     * @param amdtCache
     */
  
  
    static serializeAppMetadata(amdtCache) {
      const appMetadata = {};
      Object.keys(amdtCache).map(function (key) {
        const amdtEntity = amdtCache[key];
        appMetadata[key] = {
          client_id: amdtEntity.clientId,
          environment: amdtEntity.environment,
          family_id: amdtEntity.familyId
        };
      });
      return appMetadata;
    }
    /**
     * Serialize the cache
     * @param jsonContent
     */
  
  
    static serializeAllCache(inMemCache) {
      return {
        Account: this.serializeAccounts(inMemCache.accounts),
        IdToken: this.serializeIdTokens(inMemCache.idTokens),
        AccessToken: this.serializeAccessTokens(inMemCache.accessTokens),
        RefreshToken: this.serializeRefreshTokens(inMemCache.refreshTokens),
        AppMetadata: this.serializeAppMetadata(inMemCache.appMetadata)
      };
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  /**
   * This class implements Storage for node, reading cache from user specified storage location or an  extension library
   * @public
   */
  
  class NodeStorage extends CacheManager {
    constructor(logger, clientId, cryptoImpl) {
      super(clientId, cryptoImpl);
      this.cache = {};
      this.changeEmitters = [];
      this.logger = logger;
    }
    /**
     * Queue up callbacks
     * @param func - a callback function for cache change indication
     */
  
  
    registerChangeEmitter(func) {
      this.changeEmitters.push(func);
    }
    /**
     * Invoke the callback when cache changes
     */
  
  
    emitChange() {
      this.changeEmitters.forEach(func => func.call(null));
    }
    /**
     * Converts cacheKVStore to InMemoryCache
     * @param cache - key value store
     */
  
  
    cacheToInMemoryCache(cache) {
      const inMemoryCache = {
        accounts: {},
        idTokens: {},
        accessTokens: {},
        refreshTokens: {},
        appMetadata: {}
      };
  
      for (const key in cache) {
        if (cache[key] instanceof AccountEntity) {
          inMemoryCache.accounts[key] = cache[key];
        } else if (cache[key] instanceof IdTokenEntity) {
          inMemoryCache.idTokens[key] = cache[key];
        } else if (cache[key] instanceof AccessTokenEntity) {
          inMemoryCache.accessTokens[key] = cache[key];
        } else if (cache[key] instanceof RefreshTokenEntity) {
          inMemoryCache.refreshTokens[key] = cache[key];
        } else if (cache[key] instanceof AppMetadataEntity) {
          inMemoryCache.appMetadata[key] = cache[key];
        } else {
          continue;
        }
      }
  
      return inMemoryCache;
    }
    /**
     * converts inMemoryCache to CacheKVStore
     * @param inMemoryCache - kvstore map for inmemory
     */
  
  
    inMemoryCacheToCache(inMemoryCache) {
      // convert in memory cache to a flat Key-Value map
      let cache = this.getCache();
      cache = { ...inMemoryCache.accounts,
        ...inMemoryCache.idTokens,
        ...inMemoryCache.accessTokens,
        ...inMemoryCache.refreshTokens,
        ...inMemoryCache.appMetadata
      };
      return cache;
    }
    /**
     * gets the current in memory cache for the client
     */
  
  
    getInMemoryCache() {
      this.logger.trace("Getting in-memory cache"); // convert the cache key value store to inMemoryCache
  
      const inMemoryCache = this.cacheToInMemoryCache(this.getCache());
      return inMemoryCache;
    }
    /**
     * sets the current in memory cache for the client
     * @param inMemoryCache - key value map in memory
     */
  
  
    setInMemoryCache(inMemoryCache) {
      this.logger.trace("Setting in-memory cache"); // convert and append the inMemoryCache to cacheKVStore
  
      const cache = this.inMemoryCacheToCache(inMemoryCache);
      this.setCache(cache);
      this.emitChange();
    }
    /**
     * get the current cache key-value store
     */
  
  
    getCache() {
      this.logger.trace("Getting cache key-value store");
      return this.cache;
    }
    /**
     * sets the current cache (key value store)
     * @param cacheMap - key value map
     */
  
  
    setCache(cache) {
      this.logger.trace("Setting cache key value store");
      this.cache = cache; // mark change in cache
  
      this.emitChange();
    }
    /**
     * Gets cache item with given key.
     * @param key - lookup key for the cache entry
     */
  
  
    getItem(key) {
      this.logger.tracePii(`Item key: ${key}`); // read cache
  
      const cache = this.getCache();
      return cache[key];
    }
    /**
     * Gets cache item with given key-value
     * @param key - lookup key for the cache entry
     * @param value - value of the cache entry
     */
  
  
    setItem(key, value) {
      this.logger.tracePii(`Item key: ${key}`); // read cache
  
      const cache = this.getCache();
      cache[key] = value; // write to cache
  
      this.setCache(cache);
    }
    /**
     * fetch the account entity
     * @param accountKey - lookup key to fetch cache type AccountEntity
     */
  
  
    getAccount(accountKey) {
      const account = this.getItem(accountKey);
  
      if (AccountEntity.isAccountEntity(account)) {
        return account;
      }
  
      return null;
    }
    /**
     * set account entity
     * @param account - cache value to be set of type AccountEntity
     */
  
  
    setAccount(account) {
      const accountKey = account.generateAccountKey();
      this.setItem(accountKey, account);
    }
    /**
     * fetch the idToken credential
     * @param idTokenKey - lookup key to fetch cache type IdTokenEntity
     */
  
  
    getIdTokenCredential(idTokenKey) {
      const idToken = this.getItem(idTokenKey);
  
      if (IdTokenEntity.isIdTokenEntity(idToken)) {
        return idToken;
      }
  
      return null;
    }
    /**
     * set idToken credential
     * @param idToken - cache value to be set of type IdTokenEntity
     */
  
  
    setIdTokenCredential(idToken) {
      const idTokenKey = idToken.generateCredentialKey();
      this.setItem(idTokenKey, idToken);
    }
    /**
     * fetch the accessToken credential
     * @param accessTokenKey - lookup key to fetch cache type AccessTokenEntity
     */
  
  
    getAccessTokenCredential(accessTokenKey) {
      const accessToken = this.getItem(accessTokenKey);
  
      if (AccessTokenEntity.isAccessTokenEntity(accessToken)) {
        return accessToken;
      }
  
      return null;
    }
    /**
     * set accessToken credential
     * @param accessToken -  cache value to be set of type AccessTokenEntity
     */
  
  
    setAccessTokenCredential(accessToken) {
      const accessTokenKey = accessToken.generateCredentialKey();
      this.setItem(accessTokenKey, accessToken);
    }
    /**
     * fetch the refreshToken credential
     * @param refreshTokenKey - lookup key to fetch cache type RefreshTokenEntity
     */
  
  
    getRefreshTokenCredential(refreshTokenKey) {
      const refreshToken = this.getItem(refreshTokenKey);
  
      if (RefreshTokenEntity.isRefreshTokenEntity(refreshToken)) {
        return refreshToken;
      }
  
      return null;
    }
    /**
     * set refreshToken credential
     * @param refreshToken - cache value to be set of type RefreshTokenEntity
     */
  
  
    setRefreshTokenCredential(refreshToken) {
      const refreshTokenKey = refreshToken.generateCredentialKey();
      this.setItem(refreshTokenKey, refreshToken);
    }
    /**
     * fetch appMetadata entity from the platform cache
     * @param appMetadataKey - lookup key to fetch cache type AppMetadataEntity
     */
  
  
    getAppMetadata(appMetadataKey) {
      const appMetadata = this.getItem(appMetadataKey);
  
      if (AppMetadataEntity.isAppMetadataEntity(appMetadataKey, appMetadata)) {
        return appMetadata;
      }
  
      return null;
    }
    /**
     * set appMetadata entity to the platform cache
     * @param appMetadata - cache value to be set of type AppMetadataEntity
     */
  
  
    setAppMetadata(appMetadata) {
      const appMetadataKey = appMetadata.generateAppMetadataKey();
      this.setItem(appMetadataKey, appMetadata);
    }
    /**
     * fetch server telemetry entity from the platform cache
     * @param serverTelemetrykey - lookup key to fetch cache type ServerTelemetryEntity
     */
  
  
    getServerTelemetry(serverTelemetrykey) {
      const serverTelemetryEntity = this.getItem(serverTelemetrykey);
  
      if (serverTelemetryEntity && ServerTelemetryEntity.isServerTelemetryEntity(serverTelemetrykey, serverTelemetryEntity)) {
        return serverTelemetryEntity;
      }
  
      return null;
    }
    /**
     * set server telemetry entity to the platform cache
     * @param serverTelemetryKey - lookup key to fetch cache type ServerTelemetryEntity
     * @param serverTelemetry - cache value to be set of type ServerTelemetryEntity
     */
  
  
    setServerTelemetry(serverTelemetryKey, serverTelemetry) {
      this.setItem(serverTelemetryKey, serverTelemetry);
    }
    /**
     * fetch authority metadata entity from the platform cache
     * @param key - lookup key to fetch cache type AuthorityMetadataEntity
     */
  
  
    getAuthorityMetadata(key) {
      const authorityMetadataEntity = this.getItem(key);
  
      if (authorityMetadataEntity && AuthorityMetadataEntity.isAuthorityMetadataEntity(key, authorityMetadataEntity)) {
        return authorityMetadataEntity;
      }
  
      return null;
    }
    /**
     * Get all authority metadata keys
     */
  
  
    getAuthorityMetadataKeys() {
      return this.getKeys().filter(key => {
        return this.isAuthorityMetadata(key);
      });
    }
    /**
     * set authority metadata entity to the platform cache
     * @param key - lookup key to fetch cache type AuthorityMetadataEntity
     * @param metadata - cache value to be set of type AuthorityMetadataEntity
     */
  
  
    setAuthorityMetadata(key, metadata) {
      this.setItem(key, metadata);
    }
    /**
     * fetch throttling entity from the platform cache
     * @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity
     */
  
  
    getThrottlingCache(throttlingCacheKey) {
      const throttlingCache = this.getItem(throttlingCacheKey);
  
      if (throttlingCache && ThrottlingEntity.isThrottlingEntity(throttlingCacheKey, throttlingCache)) {
        return throttlingCache;
      }
  
      return null;
    }
    /**
     * set throttling entity to the platform cache
     * @param throttlingCacheKey - lookup key to fetch cache type ThrottlingEntity
     * @param throttlingCache - cache value to be set of type ThrottlingEntity
     */
  
  
    setThrottlingCache(throttlingCacheKey, throttlingCache) {
      this.setItem(throttlingCacheKey, throttlingCache);
    }
    /**
     * Removes the cache item from memory with the given key.
     * @param key - lookup key to remove a cache entity
     * @param inMemory - key value map of the cache
     */
  
  
    removeItem(key) {
      this.logger.tracePii(`Item key: ${key}`); // read inMemoryCache
  
      let result = false;
      const cache = this.getCache();
  
      if (!!cache[key]) {
        delete cache[key];
        result = true;
      } // write to the cache after removal
  
  
      if (result) {
        this.setCache(cache);
        this.emitChange();
      }
  
      return result;
    }
    /**
     * Checks whether key is in cache.
     * @param key - look up key for a cache entity
     */
  
  
    containsKey(key) {
      return this.getKeys().includes(key);
    }
    /**
     * Gets all keys in window.
     */
  
  
    getKeys() {
      this.logger.trace("Retrieving all cache keys"); // read cache
  
      const cache = this.getCache();
      return [...Object.keys(cache)];
    }
    /**
     * Clears all cache entries created by MSAL (except tokens).
     */
  
  
    async clear() {
      this.logger.trace("Clearing cache entries created by MSAL"); // read inMemoryCache
  
      const cacheKeys = this.getKeys(); // delete each element
  
      cacheKeys.forEach(key => {
        this.removeItem(key);
      });
      this.emitChange();
    }
    /**
     * Initialize in memory cache from an exisiting cache vault
     * @param cache - blob formatted cache (JSON)
     */
  
  
    static generateInMemoryCache(cache) {
      return Deserializer.deserializeAllCache(Deserializer.deserializeJSONBlob(cache));
    }
    /**
     * retrieves the final JSON
     * @param inMemoryCache - itemised cache read from the JSON
     */
  
  
    static generateJsonCache(inMemoryCache) {
      return Serializer.serializeAllCache(inMemoryCache);
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  const defaultSerializedCache = {
    Account: {},
    IdToken: {},
    AccessToken: {},
    RefreshToken: {},
    AppMetadata: {}
  };
  /**
   * In-memory token cache manager
   * @public
   */
  
  class TokenCache {
    constructor(storage, logger, cachePlugin) {
      this.cacheHasChanged = false;
      this.storage = storage;
      this.storage.registerChangeEmitter(this.handleChangeEvent.bind(this));
  
      if (cachePlugin) {
        this.persistence = cachePlugin;
      }
  
      this.logger = logger;
    }
    /**
     * Set to true if cache state has changed since last time serialize or writeToPersistence was called
     */
  
  
    hasChanged() {
      return this.cacheHasChanged;
    }
    /**
     * Serializes in memory cache to JSON
     */
  
  
    serialize() {
      this.logger.trace("Serializing in-memory cache");
      let finalState = Serializer.serializeAllCache(this.storage.getInMemoryCache()); // if cacheSnapshot not null or empty, merge
  
      if (!StringUtils.isEmpty(this.cacheSnapshot)) {
        this.logger.trace("Reading cache snapshot from disk");
        finalState = this.mergeState(JSON.parse(this.cacheSnapshot), finalState);
      } else {
        this.logger.trace("No cache snapshot to merge");
      }
  
      this.cacheHasChanged = false;
      return JSON.stringify(finalState);
    }
    /**
     * Deserializes JSON to in-memory cache. JSON should be in MSAL cache schema format
     * @param cache - blob formatted cache
     */
  
  
    deserialize(cache) {
      this.logger.trace("Deserializing JSON to in-memory cache");
      this.cacheSnapshot = cache;
  
      if (!StringUtils.isEmpty(this.cacheSnapshot)) {
        this.logger.trace("Reading cache snapshot from disk");
        const deserializedCache = Deserializer.deserializeAllCache(this.overlayDefaults(JSON.parse(this.cacheSnapshot)));
        this.storage.setInMemoryCache(deserializedCache);
      } else {
        this.logger.trace("No cache snapshot to deserialize");
      }
    }
    /**
     * Fetches the cache key-value map
     */
  
  
    getKVStore() {
      return this.storage.getCache();
    }
    /**
     * API that retrieves all accounts currently in cache to the user
     */
  
  
    async getAllAccounts() {
      this.logger.trace("getAllAccounts called");
      let cacheContext;
  
      try {
        if (this.persistence) {
          cacheContext = new TokenCacheContext(this, false);
          await this.persistence.beforeCacheAccess(cacheContext);
        }
  
        return this.storage.getAllAccounts();
      } finally {
        if (this.persistence && cacheContext) {
          await this.persistence.afterCacheAccess(cacheContext);
        }
      }
    }
    /**
     * Returns the signed in account matching homeAccountId.
     * (the account object is created at the time of successful login)
     * or null when no matching account is found
     * @param homeAccountId - unique identifier for an account (uid.utid)
     */
  
  
    async getAccountByHomeId(homeAccountId) {
      const allAccounts = await this.getAllAccounts();
  
      if (!StringUtils.isEmpty(homeAccountId) && allAccounts && allAccounts.length) {
        return allAccounts.filter(accountObj => accountObj.homeAccountId === homeAccountId)[0] || null;
      } else {
        return null;
      }
    }
    /**
     * Returns the signed in account matching localAccountId.
     * (the account object is created at the time of successful login)
     * or null when no matching account is found
     * @param localAccountId - unique identifier of an account (sub/obj when homeAccountId cannot be populated)
     */
  
  
    async getAccountByLocalId(localAccountId) {
      const allAccounts = await this.getAllAccounts();
  
      if (!StringUtils.isEmpty(localAccountId) && allAccounts && allAccounts.length) {
        return allAccounts.filter(accountObj => accountObj.localAccountId === localAccountId)[0] || null;
      } else {
        return null;
      }
    }
    /**
     * API to remove a specific account and the relevant data from cache
     * @param account - AccountInfo passed by the user
     */
  
  
    async removeAccount(account) {
      this.logger.trace("removeAccount called");
      let cacheContext;
  
      try {
        if (this.persistence) {
          cacheContext = new TokenCacheContext(this, true);
          await this.persistence.beforeCacheAccess(cacheContext);
        }
  
        await this.storage.removeAccount(AccountEntity.generateAccountCacheKey(account));
      } finally {
        if (this.persistence && cacheContext) {
          await this.persistence.afterCacheAccess(cacheContext);
        }
      }
    }
    /**
     * Called when the cache has changed state.
     */
  
  
    handleChangeEvent() {
      this.cacheHasChanged = true;
    }
    /**
     * Merge in memory cache with the cache snapshot.
     * @param oldState - cache before changes
     * @param currentState - current cache state in the library
     */
  
  
    mergeState(oldState, currentState) {
      this.logger.trace("Merging in-memory cache with cache snapshot");
      const stateAfterRemoval = this.mergeRemovals(oldState, currentState);
      return this.mergeUpdates(stateAfterRemoval, currentState);
    }
    /**
     * Deep update of oldState based on newState values
     * @param oldState - cache before changes
     * @param newState - updated cache
     */
  
  
    mergeUpdates(oldState, newState) {
      Object.keys(newState).forEach(newKey => {
        const newValue = newState[newKey]; // if oldState does not contain value but newValue does, add it
  
        if (!oldState.hasOwnProperty(newKey)) {
          if (newValue !== null) {
            oldState[newKey] = newValue;
          }
        } else {
          // both oldState and newState contain the key, do deep update
          const newValueNotNull = newValue !== null;
          const newValueIsObject = typeof newValue === "object";
          const newValueIsNotArray = !Array.isArray(newValue);
          const oldStateNotUndefinedOrNull = typeof oldState[newKey] !== "undefined" && oldState[newKey] !== null;
  
          if (newValueNotNull && newValueIsObject && newValueIsNotArray && oldStateNotUndefinedOrNull) {
            this.mergeUpdates(oldState[newKey], newValue);
          } else {
            oldState[newKey] = newValue;
          }
        }
      });
      return oldState;
    }
    /**
     * Removes entities in oldState that the were removed from newState. If there are any unknown values in root of
     * oldState that are not recognized, they are left untouched.
     * @param oldState - cache before changes
     * @param newState - updated cache
     */
  
  
    mergeRemovals(oldState, newState) {
      this.logger.trace("Remove updated entries in cache");
      const accounts = oldState.Account ? this.mergeRemovalsDict(oldState.Account, newState.Account) : oldState.Account;
      const accessTokens = oldState.AccessToken ? this.mergeRemovalsDict(oldState.AccessToken, newState.AccessToken) : oldState.AccessToken;
      const refreshTokens = oldState.RefreshToken ? this.mergeRemovalsDict(oldState.RefreshToken, newState.RefreshToken) : oldState.RefreshToken;
      const idTokens = oldState.IdToken ? this.mergeRemovalsDict(oldState.IdToken, newState.IdToken) : oldState.IdToken;
      const appMetadata = oldState.AppMetadata ? this.mergeRemovalsDict(oldState.AppMetadata, newState.AppMetadata) : oldState.AppMetadata;
      return { ...oldState,
        Account: accounts,
        AccessToken: accessTokens,
        RefreshToken: refreshTokens,
        IdToken: idTokens,
        AppMetadata: appMetadata
      };
    }
    /**
     * Helper to merge new cache with the old one
     * @param oldState - cache before changes
     * @param newState - updated cache
     */
  
  
    mergeRemovalsDict(oldState, newState) {
      const finalState = { ...oldState
      };
      Object.keys(oldState).forEach(oldKey => {
        if (!newState || !newState.hasOwnProperty(oldKey)) {
          delete finalState[oldKey];
        }
      });
      return finalState;
    }
    /**
     * Helper to overlay as a part of cache merge
     * @param passedInCache - cache read from the blob
     */
  
  
    overlayDefaults(passedInCache) {
      this.logger.trace("Overlaying input cache with the default cache");
      return {
        Account: { ...defaultSerializedCache.Account,
          ...passedInCache.Account
        },
        IdToken: { ...defaultSerializedCache.IdToken,
          ...passedInCache.IdToken
        },
        AccessToken: { ...defaultSerializedCache.AccessToken,
          ...passedInCache.AccessToken
        },
        RefreshToken: { ...defaultSerializedCache.RefreshToken,
          ...passedInCache.RefreshToken
        },
        AppMetadata: { ...defaultSerializedCache.AppMetadata,
          ...passedInCache.AppMetadata
        }
      };
    }
  
  }
  
  /* eslint-disable header/header */
  const name = "@azure/msal-node";
  const version = "1.3.1";
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  /**
   * Base abstract class for all ClientApplications - public and confidential
   * @public
   */
  
  class ClientApplication {
    /**
     * Constructor for the ClientApplication
     */
    constructor(configuration) {
      this.config = buildAppConfiguration(configuration);
      this.cryptoProvider = new CryptoProvider();
      this.logger = new Logger(this.config.system.loggerOptions, name, version);
      this.storage = new NodeStorage(this.logger, this.config.auth.clientId, this.cryptoProvider);
      this.tokenCache = new TokenCache(this.storage, this.logger, this.config.cache.cachePlugin);
    }
    /**
     * Creates the URL of the authorization request, letting the user input credentials and consent to the
     * application. The URL targets the /authorize endpoint of the authority configured in the
     * application object.
     *
     * Once the user inputs their credentials and consents, the authority will send a response to the redirect URI
     * sent in the request and should contain an authorization code, which can then be used to acquire tokens via
     * `acquireTokenByCode(AuthorizationCodeRequest)`.
     */
  
  
    async getAuthCodeUrl(request) {
      this.logger.info("getAuthCodeUrl called", request.correlationId);
      const validRequest = { ...request,
        ...this.initializeBaseRequest(request),
        responseMode: request.responseMode || ResponseMode.QUERY,
        authenticationScheme: AuthenticationScheme.BEARER
      };
      const authClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId);
      const authorizationCodeClient = new AuthorizationCodeClient(authClientConfig);
      this.logger.verbose("Auth code client created", validRequest.correlationId);
      return authorizationCodeClient.getAuthCodeUrl(validRequest);
    }
    /**
     * Acquires a token by exchanging the Authorization Code received from the first step of OAuth2.0
     * Authorization Code flow.
     *
     * `getAuthCodeUrl(AuthorizationCodeUrlRequest)` can be used to create the URL for the first step of OAuth2.0
     * Authorization Code flow. Ensure that values for redirectUri and scopes in AuthorizationCodeUrlRequest and
     * AuthorizationCodeRequest are the same.
     */
  
  
    async acquireTokenByCode(request) {
      this.logger.info("acquireTokenByCode called", request.correlationId);
      const validRequest = { ...request,
        ...this.initializeBaseRequest(request),
        authenticationScheme: AuthenticationScheme.BEARER
      };
      const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByCode, validRequest.correlationId);
  
      try {
        const authClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager);
        const authorizationCodeClient = new AuthorizationCodeClient(authClientConfig);
        this.logger.verbose("Auth code client created", validRequest.correlationId);
        return authorizationCodeClient.acquireToken(validRequest);
      } catch (e) {
        if (e instanceof AuthError) {
          e.setCorrelationId(validRequest.correlationId);
        }
  
        serverTelemetryManager.cacheFailedRequest(e);
        throw e;
      }
    }
    /**
     * Acquires a token by exchanging the refresh token provided for a new set of tokens.
     *
     * This API is provided only for scenarios where you would like to migrate from ADAL to MSAL. Otherwise, it is
     * recommended that you use `acquireTokenSilent()` for silent scenarios. When using `acquireTokenSilent()`, MSAL will
     * handle the caching and refreshing of tokens automatically.
     */
  
  
    async acquireTokenByRefreshToken(request) {
      this.logger.info("acquireTokenByRefreshToken called", request.correlationId);
      const validRequest = { ...request,
        ...this.initializeBaseRequest(request),
        authenticationScheme: AuthenticationScheme.BEARER
      };
      const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByRefreshToken, validRequest.correlationId);
  
      try {
        const refreshTokenClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager);
        const refreshTokenClient = new RefreshTokenClient(refreshTokenClientConfig);
        this.logger.verbose("Refresh token client created", validRequest.correlationId);
        return refreshTokenClient.acquireToken(validRequest);
      } catch (e) {
        if (e instanceof AuthError) {
          e.setCorrelationId(validRequest.correlationId);
        }
  
        serverTelemetryManager.cacheFailedRequest(e);
        throw e;
      }
    }
    /**
     * Acquires a token silently when a user specifies the account the token is requested for.
     *
     * This API expects the user to provide an account object and looks into the cache to retrieve the token if present.
     * There is also an optional "forceRefresh" boolean the user can send to bypass the cache for access_token and id_token.
     * In case the refresh_token is expired or not found, an error is thrown
     * and the guidance is for the user to call any interactive token acquisition API (eg: `acquireTokenByCode()`).
     */
  
  
    async acquireTokenSilent(request) {
      const validRequest = { ...request,
        ...this.initializeBaseRequest(request),
        forceRefresh: request.forceRefresh || false
      };
      const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenSilent, validRequest.correlationId, validRequest.forceRefresh);
  
      try {
        const silentFlowClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager);
        const silentFlowClient = new SilentFlowClient(silentFlowClientConfig);
        this.logger.verbose("Silent flow client created", validRequest.correlationId);
        return silentFlowClient.acquireToken(validRequest);
      } catch (e) {
        if (e instanceof AuthError) {
          e.setCorrelationId(validRequest.correlationId);
        }
  
        serverTelemetryManager.cacheFailedRequest(e);
        throw e;
      }
    }
    /**
     * Acquires tokens with password grant by exchanging client applications username and password for credentials
     *
     * The latest OAuth 2.0 Security Best Current Practice disallows the password grant entirely.
     * More details on this recommendation at https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13#section-3.4
     * Microsoft's documentation and recommendations are at:
     * https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-authentication-flows#usernamepassword
     *
     * @param request - UsenamePasswordRequest
     */
  
  
    async acquireTokenByUsernamePassword(request) {
      this.logger.info("acquireTokenByUsernamePassword called", request.correlationId);
      const validRequest = { ...request,
        ...this.initializeBaseRequest(request)
      };
      const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByUsernamePassword, validRequest.correlationId);
  
      try {
        const usernamePasswordClientConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager);
        const usernamePasswordClient = new UsernamePasswordClient(usernamePasswordClientConfig);
        this.logger.verbose("Username password client created", validRequest.correlationId);
        return usernamePasswordClient.acquireToken(validRequest);
      } catch (e) {
        if (e instanceof AuthError) {
          e.setCorrelationId(validRequest.correlationId);
        }
  
        serverTelemetryManager.cacheFailedRequest(e);
        throw e;
      }
    }
    /**
     * Gets the token cache for the application.
     */
  
  
    getTokenCache() {
      this.logger.info("getTokenCache called");
      return this.tokenCache;
    }
    /**
     * Returns the logger instance
     */
  
  
    getLogger() {
      return this.logger;
    }
    /**
     * Replaces the default logger set in configurations with new Logger with new configurations
     * @param logger - Logger instance
     */
  
  
    setLogger(logger) {
      this.logger = logger;
    }
    /**
     * Builds the common configuration to be passed to the common component based on the platform configurarion
     * @param authority - user passed authority in configuration
     * @param serverTelemetryManager - initializes servertelemetry if passed
     */
  
  
    async buildOauthClientConfiguration(authority, requestCorrelationId, serverTelemetryManager, azureRegionConfiguration) {
      this.logger.verbose("buildOauthClientConfiguration called", requestCorrelationId); // using null assertion operator as we ensure that all config values have default values in buildConfiguration()
  
      this.logger.verbose(`building oauth client configuration with the authority: ${authority}`, requestCorrelationId);
      const discoveredAuthority = await this.createAuthority(authority, azureRegionConfiguration, requestCorrelationId);
      serverTelemetryManager == null ? void 0 : serverTelemetryManager.updateRegionDiscoveryMetadata(discoveredAuthority.regionDiscoveryMetadata);
      return {
        authOptions: {
          clientId: this.config.auth.clientId,
          authority: discoveredAuthority,
          clientCapabilities: this.config.auth.clientCapabilities
        },
        loggerOptions: {
          logLevel: this.config.system.loggerOptions.logLevel,
          loggerCallback: this.config.system.loggerOptions.loggerCallback,
          piiLoggingEnabled: this.config.system.loggerOptions.piiLoggingEnabled,
          correlationId: requestCorrelationId
        },
        cryptoInterface: this.cryptoProvider,
        networkInterface: this.config.system.networkClient,
        storageInterface: this.storage,
        serverTelemetryManager: serverTelemetryManager,
        clientCredentials: {
          clientSecret: this.clientSecret,
          clientAssertion: this.clientAssertion ? this.getClientAssertion(discoveredAuthority) : undefined
        },
        libraryInfo: {
          sku: Constants.MSAL_SKU,
          version: version,
          cpu: process.arch || "",
          os: process.platform || ""
        },
        persistencePlugin: this.config.cache.cachePlugin,
        serializableCache: this.tokenCache
      };
    }
  
    getClientAssertion(authority) {
      return {
        assertion: this.clientAssertion.getJwt(this.cryptoProvider, this.config.auth.clientId, authority.tokenEndpoint),
        assertionType: Constants.JWT_BEARER_ASSERTION_TYPE
      };
    }
    /**
     * Generates a request with the default scopes & generates a correlationId.
     * @param authRequest - BaseAuthRequest for initialization
     */
  
  
    initializeBaseRequest(authRequest) {
      this.logger.verbose("initializeRequestScopes called", authRequest.correlationId); // Default authenticationScheme to Bearer, log that POP isn't supported yet
  
      if (authRequest.authenticationScheme && authRequest.authenticationScheme === AuthenticationScheme.POP) {
        this.logger.verbose("Authentication Scheme 'pop' is not supported yet, setting Authentication Scheme to 'Bearer' for request", authRequest.correlationId);
      }
  
      authRequest.authenticationScheme = AuthenticationScheme.BEARER;
      return { ...authRequest,
        scopes: [...(authRequest && authRequest.scopes || []), ...OIDC_DEFAULT_SCOPES],
        correlationId: authRequest && authRequest.correlationId || this.cryptoProvider.createNewGuid(),
        authority: authRequest.authority || this.config.auth.authority
      };
    }
    /**
     * Initializes the server telemetry payload
     * @param apiId - Id for a specific request
     * @param correlationId - GUID
     * @param forceRefresh - boolean to indicate network call
     */
  
  
    initializeServerTelemetryManager(apiId, correlationId, forceRefresh) {
      const telemetryPayload = {
        clientId: this.config.auth.clientId,
        correlationId: correlationId,
        apiId: apiId,
        forceRefresh: forceRefresh || false
      };
      return new ServerTelemetryManager(telemetryPayload, this.storage);
    }
    /**
     * Create authority instance. If authority not passed in request, default to authority set on the application
     * object. If no authority set in application object, then default to common authority.
     * @param authorityString - authority from user configuration
     */
  
  
    async createAuthority(authorityString, azureRegionConfiguration, requestCorrelationId) {
      this.logger.verbose("createAuthority called", requestCorrelationId);
      const authorityOptions = {
        protocolMode: this.config.auth.protocolMode,
        knownAuthorities: this.config.auth.knownAuthorities,
        cloudDiscoveryMetadata: this.config.auth.cloudDiscoveryMetadata,
        authorityMetadata: this.config.auth.authorityMetadata,
        azureRegionConfiguration
      };
      return await AuthorityFactory.createDiscoveredInstance(authorityString, this.config.system.networkClient, this.storage, authorityOptions);
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  /**
   * This class is to be used to acquire tokens for public client applications (desktop, mobile). Public client applications
   * are not trusted to safely store application secrets, and therefore can only request tokens in the name of an user.
   * @public
   */
  
  class PublicClientApplication extends ClientApplication {
    /**
     * Important attributes in the Configuration object for auth are:
     * - clientID: the application ID of your application. You can obtain one by registering your application with our Application registration portal.
     * - authority: the authority URL for your application.
     *
     * AAD authorities are of the form https://login.microsoftonline.com/\{Enter_the_Tenant_Info_Here\}.
     * - If your application supports Accounts in one organizational directory, replace "Enter_the_Tenant_Info_Here" value with the Tenant Id or Tenant name (for example, contoso.microsoft.com).
     * - If your application supports Accounts in any organizational directory, replace "Enter_the_Tenant_Info_Here" value with organizations.
     * - If your application supports Accounts in any organizational directory and personal Microsoft accounts, replace "Enter_the_Tenant_Info_Here" value with common.
     * - To restrict support to Personal Microsoft accounts only, replace "Enter_the_Tenant_Info_Here" value with consumers.
     *
     * Azure B2C authorities are of the form https://\{instance\}/\{tenant\}/\{policy\}. Each policy is considered
     * its own authority. You will have to set the all of the knownAuthorities at the time of the client application
     * construction.
     *
     * ADFS authorities are of the form https://\{instance\}/adfs.
     */
    constructor(configuration) {
      super(configuration);
    }
    /**
     * Acquires a token from the authority using OAuth2.0 device code flow.
     * This flow is designed for devices that do not have access to a browser or have input constraints.
     * The authorization server issues a DeviceCode object with a verification code, an end-user code,
     * and the end-user verification URI. The DeviceCode object is provided through a callback, and the end-user should be
     * instructed to use another device to navigate to the verification URI to input credentials.
     * Since the client cannot receive incoming requests, it polls the authorization server repeatedly
     * until the end-user completes input of credentials.
     */
  
  
    async acquireTokenByDeviceCode(request) {
      this.logger.info("acquireTokenByDeviceCode called", request.correlationId);
      const validRequest = Object.assign(request, this.initializeBaseRequest(request));
      const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByDeviceCode, validRequest.correlationId);
  
      try {
        const deviceCodeConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager);
        const deviceCodeClient = new DeviceCodeClient(deviceCodeConfig);
        this.logger.verbose("Device code client created", validRequest.correlationId);
        return deviceCodeClient.acquireToken(validRequest);
      } catch (e) {
        if (e instanceof AuthError) {
          e.setCorrelationId(validRequest.correlationId);
        }
  
        serverTelemetryManager.cacheFailedRequest(e);
        throw e;
      }
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  /**
   * Client assertion of type jwt-bearer used in confidential client flows
   * @public
   */
  
  class ClientAssertion {
    /**
     * Initialize the ClientAssertion class from the clientAssertion passed by the user
     * @param assertion - refer https://tools.ietf.org/html/rfc7521
     */
    static fromAssertion(assertion) {
      const clientAssertion = new ClientAssertion();
      clientAssertion.jwt = assertion;
      return clientAssertion;
    }
    /**
     * Initialize the ClientAssertion class from the certificate passed by the user
     * @param thumbprint - identifier of a certificate
     * @param privateKey - secret key
     * @param publicCertificate - electronic document provided to prove the ownership of the public key
     */
  
  
    static fromCertificate(thumbprint, privateKey, publicCertificate) {
      const clientAssertion = new ClientAssertion();
      clientAssertion.privateKey = privateKey;
      clientAssertion.thumbprint = thumbprint;
  
      if (publicCertificate) {
        clientAssertion.publicCertificate = this.parseCertificate(publicCertificate);
      }
  
      return clientAssertion;
    }
    /**
     * Update JWT for certificate based clientAssertion, if passed by the user, uses it as is
     * @param cryptoProvider - library's crypto helper
     * @param issuer - iss claim
     * @param jwtAudience - aud claim
     */
  
  
    getJwt(cryptoProvider, issuer, jwtAudience) {
      // if assertion was created from certificate, check if jwt is expired and create new one.
      if (this.privateKey && this.thumbprint) {
        if (this.jwt && !this.isExpired() && issuer === this.issuer && jwtAudience === this.jwtAudience) {
          return this.jwt;
        }
  
        return this.createJwt(cryptoProvider, issuer, jwtAudience);
      }
      /*
       * if assertion was created by caller, then we just append it. It is up to the caller to
       * ensure that it contains necessary claims and that it is not expired.
       */
  
  
      if (this.jwt) {
        return this.jwt;
      }
  
      throw ClientAuthError.createInvalidAssertionError();
    }
    /**
     * JWT format and required claims specified: https://tools.ietf.org/html/rfc7523#section-3
     */
  
  
    createJwt(cryptoProvider, issuer, jwtAudience) {
      this.issuer = issuer;
      this.jwtAudience = jwtAudience;
      const issuedAt = TimeUtils.nowSeconds();
      this.expirationTime = issuedAt + 600;
      const header = {
        [JwtConstants.ALGORITHM]: JwtConstants.RSA_256,
        [JwtConstants.X5T]: EncodingUtils.base64EncodeUrl(this.thumbprint, "hex")
      };
  
      if (this.publicCertificate) {
        Object.assign(header, {
          [JwtConstants.X5C]: this.publicCertificate
        });
      }
  
      const payload = {
        [JwtConstants.AUDIENCE]: this.jwtAudience,
        [JwtConstants.EXPIRATION_TIME]: this.expirationTime,
        [JwtConstants.ISSUER]: this.issuer,
        [JwtConstants.SUBJECT]: this.issuer,
        [JwtConstants.NOT_BEFORE]: issuedAt,
        [JwtConstants.JWT_ID]: cryptoProvider.createNewGuid()
      };
      this.jwt = sign(payload, this.privateKey, {
        header: header
      });
      return this.jwt;
    }
    /**
     * Utility API to check expiration
     */
  
  
    isExpired() {
      return this.expirationTime < TimeUtils.nowSeconds();
    }
    /**
     * Extracts the raw certs from a given certificate string and returns them in an array.
     * @param publicCertificate - electronic document provided to prove the ownership of the public key
     */
  
  
    static parseCertificate(publicCertificate) {
      /**
       * This is regex to identify the certs in a given certificate string.
       * We want to look for the contents between the BEGIN and END certificate strings, without the associated newlines.
       * The information in parens "(.+?)" is the capture group to represent the cert we want isolated.
       * "." means any string character, "+" means match 1 or more times, and "?" means the shortest match.
       * The "g" at the end of the regex means search the string globally, and the "s" enables the "." to match newlines.
       */
      const regexToFindCerts = /-----BEGIN CERTIFICATE-----\n(.+?)\n-----END CERTIFICATE-----/gs;
      const certs = [];
      let matches;
  
      while ((matches = regexToFindCerts.exec(publicCertificate)) !== null) {
        // matches[1] represents the first parens capture group in the regex.
        certs.push(matches[1].replace(/\n/, ""));
      }
  
      return certs;
    }
  
  }
  
  /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License.
   */
  /**
   *  This class is to be used to acquire tokens for confidential client applications (webApp, webAPI). Confidential client applications
   *  will configure application secrets, client certificates/assertions as applicable
   * @public
   */
  
  class ConfidentialClientApplication extends ClientApplication {
    /**
     * Constructor for the ConfidentialClientApplication
     *
     * Required attributes in the Configuration object are:
     * - clientID: the application ID of your application. You can obtain one by registering your application with our application registration portal
     * - authority: the authority URL for your application.
     * - client credential: Must set either client secret, certificate, or assertion for confidential clients. You can obtain a client secret from the application registration portal.
     *
     * In Azure AD, authority is a URL indicating of the form https://login.microsoftonline.com/\{Enter_the_Tenant_Info_Here\}.
     * If your application supports Accounts in one organizational directory, replace "Enter_the_Tenant_Info_Here" value with the Tenant Id or Tenant name (for example, contoso.microsoft.com).
     * If your application supports Accounts in any organizational directory, replace "Enter_the_Tenant_Info_Here" value with organizations.
     * If your application supports Accounts in any organizational directory and personal Microsoft accounts, replace "Enter_the_Tenant_Info_Here" value with common.
     * To restrict support to Personal Microsoft accounts only, replace "Enter_the_Tenant_Info_Here" value with consumers.
     *
     * In Azure B2C, authority is of the form https://\{instance\}/tfp/\{tenant\}/\{policyName\}/
     * Full B2C functionality will be available in this library in future versions.
     *
     * @param Configuration - configuration object for the MSAL ConfidentialClientApplication instance
     */
    constructor(configuration) {
      super(configuration);
      this.setClientCredential(this.config);
    }
    /**
     * Acquires tokens from the authority for the application (not for an end user).
     */
  
  
    async acquireTokenByClientCredential(request) {
      this.logger.info("acquireTokenByClientCredential called", request.correlationId);
      const validRequest = { ...request,
        ...this.initializeBaseRequest(request)
      };
      const azureRegionConfiguration = {
        azureRegion: validRequest.azureRegion,
        environmentRegion: process.env[REGION_ENVIRONMENT_VARIABLE]
      };
      const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenByClientCredential, validRequest.correlationId, validRequest.skipCache);
  
      try {
        const clientCredentialConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId, serverTelemetryManager, azureRegionConfiguration);
        const clientCredentialClient = new ClientCredentialClient(clientCredentialConfig);
        this.logger.verbose("Client credential client created", validRequest.correlationId);
        return clientCredentialClient.acquireToken(validRequest);
      } catch (e) {
        if (e instanceof AuthError) {
          e.setCorrelationId(validRequest.correlationId);
        }
  
        serverTelemetryManager.cacheFailedRequest(e);
        throw e;
      }
    }
    /**
     * Acquires tokens from the authority for the application.
     *
     * Used in scenarios where the current app is a middle-tier service which was called with a token
     * representing an end user. The current app can use the token (oboAssertion) to request another
     * token to access downstream web API, on behalf of that user.
     *
     * The current middle-tier app has no user interaction to obtain consent.
     * See how to gain consent upfront for your middle-tier app from this article.
     * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow#gaining-consent-for-the-middle-tier-application
     */
  
  
    async acquireTokenOnBehalfOf(request) {
      this.logger.info("acquireTokenOnBehalfOf called", request.correlationId);
      const validRequest = { ...request,
        ...this.initializeBaseRequest(request)
      };
  
      try {
        const clientCredentialConfig = await this.buildOauthClientConfiguration(validRequest.authority, validRequest.correlationId);
        const oboClient = new OnBehalfOfClient(clientCredentialConfig);
        this.logger.verbose("On behalf of client created", validRequest.correlationId);
        return oboClient.acquireToken(validRequest);
      } catch (e) {
        if (e instanceof AuthError) {
          e.setCorrelationId(validRequest.correlationId);
        }
  
        throw e;
      }
    }
  
    setClientCredential(configuration) {
      const clientSecretNotEmpty = !StringUtils.isEmpty(configuration.auth.clientSecret);
      const clientAssertionNotEmpty = !StringUtils.isEmpty(configuration.auth.clientAssertion);
      const certificate = configuration.auth.clientCertificate || {
        thumbprint: "",
        privateKey: ""
      };
      const certificateNotEmpty = !StringUtils.isEmpty(certificate.thumbprint) || !StringUtils.isEmpty(certificate.privateKey); // Check that at most one credential is set on the application
  
      if (clientSecretNotEmpty && clientAssertionNotEmpty || clientAssertionNotEmpty && certificateNotEmpty || clientSecretNotEmpty && certificateNotEmpty) {
        throw ClientAuthError.createInvalidCredentialError();
      }
  
      if (configuration.auth.clientSecret) {
        this.clientSecret = configuration.auth.clientSecret;
        return;
      }
  
      if (configuration.auth.clientAssertion) {
        this.clientAssertion = ClientAssertion.fromAssertion(configuration.auth.clientAssertion);
        return;
      }
  
      if (!certificateNotEmpty) {
        throw ClientAuthError.createInvalidCredentialError();
      } else {
        var _configuration$auth$c;
  
        this.clientAssertion = ClientAssertion.fromCertificate(certificate.thumbprint, certificate.privateKey, (_configuration$auth$c = configuration.auth.clientCertificate) == null ? void 0 : _configuration$auth$c.x5c);
      }
    }
  
  }
  
  export { ClientApplication, ClientAssertion, ConfidentialClientApplication, CryptoProvider, NodeStorage, PublicClientApplication, TokenCache, buildAppConfiguration };
  //# sourceMappingURL=msal-node.esm.js.map
  