/*! @azure/msal-node-extensions v1.5.17 2025-07-08 */
'use strict';
'use strict';

var fs = require('fs');
var process$1 = require('process');
var path = require('path');
var module$1 = require('module');
var keytar = require('keytar');
var msalNodeRuntime = require('@azure/msal-node-runtime');

var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const Constants$1 = {
    /**
     * An existing file was the target of an operation that required that the target not exist
     */
    EEXIST_ERROR: "EEXIST",
    /**
     * No such file or directory: Commonly raised by fs operations to indicate that a component
     * of the specified pathname does not exist. No entity (file or directory) could be found
     * by the given path
     */
    ENOENT_ERROR: "ENOENT",
    /**
     * Operation not permitted. An attempt was made to perform an operation that requires
     * elevated privileges.
     */
    EPERM_ERROR: "EPERM",
    /**
     * Default service name for using MSAL Keytar
     */
    DEFAULT_SERVICE_NAME: "msal-node-extensions",
    /**
     * Test data used to verify underlying persistence mechanism
     */
    PERSISTENCE_TEST_DATA: "Dummy data to verify underlying persistence mechanism",
    /**
     * This is the value of a the guid if the process is being ran by the root user
     */
    LINUX_ROOT_USER_GUID: 0,
    /**
     * List of environment variables
     */
    ENVIRONMENT: {
        HOME: "HOME",
        LOGNAME: "LOGNAME",
        USER: "USER",
        LNAME: "LNAME",
        USERNAME: "USERNAME",
        PLATFORM: "platform",
        LOCAL_APPLICATION_DATA: "LOCALAPPDATA",
    },
    // Name of the default cache file
    DEFAULT_CACHE_FILE_NAME: "cache.json",
};
const Platform = {
    WINDOWS: "win32",
    LINUX: "linux",
    MACOS: "darwin",
};
const ErrorCodes = {
    INTERATION_REQUIRED_ERROR_CODE: "interaction_required",
    SERVER_UNAVAILABLE: "server_unavailable",
    UNKNOWN: "unknown_error",
};

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Error thrown when trying to write MSAL cache to persistence.
 */
class PersistenceError extends Error {
    constructor(errorCode, errorMessage) {
        const errorString = errorMessage
            ? `${errorCode}: ${errorMessage}`
            : errorCode;
        super(errorString);
        Object.setPrototypeOf(this, PersistenceError.prototype);
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
        this.name = "PersistenceError";
    }
    /**
     * Error thrown when trying to access the file system.
     */
    static createFileSystemError(errorCode, errorMessage) {
        return new PersistenceError(errorCode, errorMessage);
    }
    /**
     * Error thrown when trying to write, load, or delete data from secret service on linux.
     * Libsecret is used to access secret service.
     */
    static createLibSecretError(errorMessage) {
        return new PersistenceError("GnomeKeyringError", errorMessage);
    }
    /**
     * Error thrown when trying to write, load, or delete data from keychain on macOs.
     */
    static createKeychainPersistenceError(errorMessage) {
        return new PersistenceError("KeychainError", errorMessage);
    }
    /**
     * Error thrown when trying to encrypt or decrypt data using DPAPI on Windows.
     */
    static createFilePersistenceWithDPAPIError(errorMessage) {
        return new PersistenceError("DPAPIEncryptedFileError", errorMessage);
    }
    /**
     * Error thrown when using the cross platform lock.
     */
    static createCrossPlatformLockError(errorMessage) {
        return new PersistenceError("CrossPlatformLockError", errorMessage);
    }
    /**
     * Throw cache persistence error
     *
     * @param errorMessage string
     * @returns PersistenceError
     */
    static createCachePersistenceError(errorMessage) {
        return new PersistenceError("CachePersistenceError", errorMessage);
    }
    /**
     * Throw unsupported error
     *
     * @param errorMessage string
     * @returns PersistenceError
     */
    static createNotSupportedError(errorMessage) {
        return new PersistenceError("NotSupportedError", errorMessage);
    }
    /**
     * Throw persistence not verified error
     *
     * @param errorMessage string
     * @returns PersistenceError
     */
    static createPersistenceNotVerifiedError(errorMessage) {
        return new PersistenceError("PersistenceNotVerifiedError", errorMessage);
    }
    /**
     * Throw persistence creation validation error
     *
     * @param errorMessage string
     * @returns PersistenceError
     */
    static createPersistenceNotValidatedError(errorMessage) {
        return new PersistenceError("PersistenceNotValidatedError", errorMessage);
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Returns whether or not the given object is a Node.js error
 */
const isNodeError = (error) => {
    return !!error && typeof error === "object" && error.hasOwnProperty("code");
};

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Cross-process lock that works on all platforms.
 */
class CrossPlatformLock {
    constructor(lockFilePath, logger, lockOptions) {
        this.lockFilePath = lockFilePath;
        this.retryNumber = lockOptions ? lockOptions.retryNumber : 500;
        this.retryDelay = lockOptions ? lockOptions.retryDelay : 100;
        this.logger = logger;
    }
    /**
     * Locks cache from read or writes by creating file with same path and name as
     * cache file but with .lockfile extension. If another process has already created
     * the lockfile, will back off and retry based on configuration settings set by CrossPlatformLockOptions
     */
    async lock() {
        for (let tryCount = 0; tryCount < this.retryNumber; tryCount++) {
            try {
                this.logger.info(`Pid ${process$1.pid} trying to acquire lock`);
                this.lockFileHandle = await fs.promises.open(this.lockFilePath, "wx+");
                this.logger.info(`Pid ${process$1.pid} acquired lock`);
                await this.lockFileHandle.write(process$1.pid.toString());
                return;
            }
            catch (err) {
                if (isNodeError(err)) {
                    if (err.code === Constants$1.EEXIST_ERROR ||
                        err.code === Constants$1.EPERM_ERROR) {
                        this.logger.info(err.message);
                        await this.sleep(this.retryDelay);
                    }
                    else {
                        this.logger.error(`${process$1.pid} was not able to acquire lock. Ran into error: ${err.message}`);
                        throw PersistenceError.createCrossPlatformLockError(err.message);
                    }
                }
                else {
                    throw err;
                }
            }
        }
        this.logger.error(`${process$1.pid} was not able to acquire lock. Exceeded amount of retries set in the options`);
        throw PersistenceError.createCrossPlatformLockError("Not able to acquire lock. Exceeded amount of retries set in options");
    }
    /**
     * unlocks cache file by deleting .lockfile.
     */
    async unlock() {
        try {
            if (this.lockFileHandle) {
                // if we have a file handle to the .lockfile, delete lock file
                await fs.promises.unlink(this.lockFilePath);
                await this.lockFileHandle.close();
                this.logger.info("lockfile deleted");
            }
            else {
                this.logger.warning("lockfile handle does not exist, so lockfile could not be deleted");
            }
        }
        catch (err) {
            if (isNodeError(err)) {
                if (err.code === Constants$1.ENOENT_ERROR) {
                    this.logger.info("Tried to unlock but lockfile does not exist");
                }
                else {
                    this.logger.error(`${process$1.pid} was not able to release lock. Ran into error: ${err.message}`);
                    throw PersistenceError.createCrossPlatformLockError(err.message);
                }
            }
            else {
                throw err;
            }
        }
    }
    sleep(ms) {
        return new Promise((resolve) => {
            setTimeout(resolve, ms);
        });
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * MSAL cache plugin which enables callers to write the MSAL cache to disk on Windows,
 * macOs, and Linux.
 *
 * - Persistence can be one of:
 * - FilePersistence: Writes and reads from an unencrypted file. Can be used on Windows,
 * macOs, or Linux.
 * - FilePersistenceWithDataProtection: Used on Windows, writes and reads from file encrypted
 * with windows dpapi-addon.
 * - KeychainPersistence: Used on macOs, writes and reads from keychain.
 * - LibSecretPersistence: Used on linux, writes and reads from secret service API. Requires
 * libsecret be installed.
 */
class PersistenceCachePlugin {
    constructor(persistence, lockOptions) {
        this.persistence = persistence;
        // initialize logger
        this.logger = persistence.getLogger();
        // create file lock
        this.lockFilePath = `${this.persistence.getFilePath()}.lockfile`;
        this.crossPlatformLock = new CrossPlatformLock(this.lockFilePath, this.logger, lockOptions);
        // initialize default values
        this.lastSync = 0;
        this.currentCache = null;
    }
    /**
     * Reads from storage and saves an in-memory copy. If persistence has not been updated
     * since last time data was read, in memory copy is used.
     *
     * If cacheContext.cacheHasChanged === true, then file lock is created and not deleted until
     * afterCacheAccess() is called, to prevent the cache file from changing in between
     * beforeCacheAccess() and afterCacheAccess().
     */
    async beforeCacheAccess(cacheContext) {
        this.logger.info("Executing before cache access");
        const reloadNecessary = await this.persistence.reloadNecessary(this.lastSync);
        if (!reloadNecessary && this.currentCache !== null) {
            if (cacheContext.cacheHasChanged) {
                this.logger.verbose("Cache context has changed");
                await this.crossPlatformLock.lock();
            }
            return;
        }
        try {
            this.logger.info(`Reload necessary. Last sync time: ${this.lastSync}`);
            await this.crossPlatformLock.lock();
            this.currentCache = await this.persistence.load();
            this.lastSync = new Date().getTime();
            if (this.currentCache) {
                cacheContext.tokenCache.deserialize(this.currentCache);
            }
            else {
                this.logger.info("Cache empty.");
            }
            this.logger.info(`Last sync time updated to: ${this.lastSync}`);
        }
        finally {
            if (!cacheContext.cacheHasChanged) {
                await this.crossPlatformLock.unlock();
                this.logger.info(`Pid ${process$1.pid} released lock`);
            }
            else {
                this.logger.info(`Pid ${process$1.pid} beforeCacheAccess did not release lock`);
            }
        }
    }
    /**
     * Writes to storage if MSAL in memory copy of cache has been changed.
     */
    async afterCacheAccess(cacheContext) {
        this.logger.info("Executing after cache access");
        try {
            if (cacheContext.cacheHasChanged) {
                this.logger.info("Msal in-memory cache has changed. Writing changes to persistence");
                this.currentCache = cacheContext.tokenCache.serialize();
                await this.persistence.save(this.currentCache);
            }
            else {
                this.logger.info("Msal in-memory cache has not changed. Did not write to persistence");
            }
        }
        finally {
            await this.crossPlatformLock.unlock();
            this.logger.info(`Pid ${process$1.pid} afterCacheAccess released lock`);
        }
    }
}

/*! @azure/msal-common v15.8.1 2025-07-08 */
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const Constants = {
    LIBRARY_NAME: "MSAL.JS",
    SKU: "msal.js.common",
    // Prefix for all library cache entries
    CACHE_PREFIX: "msal",
    // default authority
    DEFAULT_AUTHORITY: "https://login.microsoftonline.com/common/",
    DEFAULT_AUTHORITY_HOST: "login.microsoftonline.com",
    DEFAULT_COMMON_TENANT: "common",
    // ADFS String
    ADFS: "adfs",
    DSTS: "dstsv2",
    // Default AAD Instance Discovery Endpoint
    AAD_INSTANCE_DISCOVERY_ENDPT: "https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=",
    // CIAM URL
    CIAM_AUTH_URL: ".ciamlogin.com",
    AAD_TENANT_DOMAIN_SUFFIX: ".onmicrosoft.com",
    // Resource delimiter - used for certain cache entries
    RESOURCE_DELIM: "|",
    // Placeholder for non-existent account ids/objects
    NO_ACCOUNT: "NO_ACCOUNT",
    // Claims
    CLAIMS: "claims",
    // Consumer UTID
    CONSUMER_UTID: "9188040d-6c67-4c5b-b112-36a304b66dad",
    // Default scopes
    OPENID_SCOPE: "openid",
    PROFILE_SCOPE: "profile",
    OFFLINE_ACCESS_SCOPE: "offline_access",
    EMAIL_SCOPE: "email",
    CODE_GRANT_TYPE: "authorization_code",
    RT_GRANT_TYPE: "refresh_token",
    S256_CODE_CHALLENGE_METHOD: "S256",
    URL_FORM_CONTENT_TYPE: "application/x-www-form-urlencoded;charset=utf-8",
    AUTHORIZATION_PENDING: "authorization_pending",
    NOT_DEFINED: "not_defined",
    EMPTY_STRING: "",
    NOT_APPLICABLE: "N/A",
    NOT_AVAILABLE: "Not Available",
    FORWARD_SLASH: "/",
    IMDS_ENDPOINT: "http://169.254.169.254/metadata/instance/compute/location",
    IMDS_VERSION: "2020-06-01",
    IMDS_TIMEOUT: 2000,
    AZURE_REGION_AUTO_DISCOVER_FLAG: "TryAutoDetect",
    REGIONAL_AUTH_PUBLIC_CLOUD_SUFFIX: "login.microsoft.com",
    KNOWN_PUBLIC_CLOUDS: [
        "login.microsoftonline.com",
        "login.windows.net",
        "login.microsoft.com",
        "sts.windows.net",
    ],
    SHR_NONCE_VALIDITY: 240,
    INVALID_INSTANCE: "invalid_instance",
};
/**
 * we considered making this "enum" in the request instead of string, however it looks like the allowed list of
 * prompt values kept changing over past couple of years. There are some undocumented prompt values for some
 * internal partners too, hence the choice of generic "string" type instead of the "enum"
 */
const PromptValue = {
    LOGIN: "login",
    SELECT_ACCOUNT: "select_account",
    CONSENT: "consent",
    NONE: "none",
    CREATE: "create",
    NO_SESSION: "no_session",
};
/**
 * Separators used in cache
 */
const Separators = {
    CACHE_KEY_SEPARATOR: "-"};
const SERVER_TELEM_CONSTANTS = {
    SCHEMA_VERSION: 5,
    MAX_LAST_HEADER_BYTES: 330,
    MAX_CACHED_ERRORS: 50,
    CACHE_KEY: "server-telemetry",
    CATEGORY_SEPARATOR: "|",
    VALUE_SEPARATOR: ",",
    OVERFLOW_TRUE: "1",
    OVERFLOW_FALSE: "0",
    UNKNOWN_ERROR: "unknown_error",
};
/**
 * Type of the authentication request
 */
const AuthenticationScheme = {
    BEARER: "Bearer",
    POP: "pop",
    SSH: "ssh-cert",
};
/**
 * Specifies the reason for fetching the access token from the identity provider
 */
const CacheOutcome = {
    // When a token is found in the cache or the cache is not supposed to be hit when making the request
    NOT_APPLICABLE: "0"};

/*! @azure/msal-common v15.8.1 2025-07-08 */
/**
 * General error class thrown by the MSAL.js library.
 */
class AuthError extends Error {
    constructor(errorCode, errorMessage, suberror) {
        const errorString = errorMessage
            ? `${errorCode}: ${errorMessage}`
            : errorCode;
        super(errorString);
        Object.setPrototypeOf(this, AuthError.prototype);
        this.errorCode = errorCode || Constants.EMPTY_STRING;
        this.errorMessage = errorMessage || Constants.EMPTY_STRING;
        this.subError = suberror || Constants.EMPTY_STRING;
        this.name = "AuthError";
    }
    setCorrelationId(correlationId) {
        this.correlationId = correlationId;
    }
}

/*! @azure/msal-common v15.8.1 2025-07-08 */
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const clientInfoDecodingError = "client_info_decoding_error";
const clientInfoEmptyError = "client_info_empty_error";
const tokenParsingError = "token_parsing_error";
const nullOrEmptyToken = "null_or_empty_token";
const endpointResolutionError = "endpoints_resolution_error";
const networkError = "network_error";
const openIdConfigError = "openid_config_error";
const hashNotDeserialized = "hash_not_deserialized";
const invalidState = "invalid_state";
const stateMismatch = "state_mismatch";
const stateNotFound = "state_not_found";
const nonceMismatch = "nonce_mismatch";
const authTimeNotFound = "auth_time_not_found";
const maxAgeTranspired = "max_age_transpired";
const multipleMatchingTokens = "multiple_matching_tokens";
const multipleMatchingAccounts = "multiple_matching_accounts";
const multipleMatchingAppMetadata = "multiple_matching_appMetadata";
const requestCannotBeMade = "request_cannot_be_made";
const cannotRemoveEmptyScope = "cannot_remove_empty_scope";
const cannotAppendScopeSet = "cannot_append_scopeset";
const emptyInputScopeSet = "empty_input_scopeset";
const deviceCodePollingCancelled = "device_code_polling_cancelled";
const deviceCodeExpired = "device_code_expired";
const deviceCodeUnknownError = "device_code_unknown_error";
const noAccountInSilentRequest = "no_account_in_silent_request";
const invalidCacheRecord = "invalid_cache_record";
const invalidCacheEnvironment = "invalid_cache_environment";
const noAccountFound = "no_account_found";
const noCryptoObject = "no_crypto_object";
const unexpectedCredentialType = "unexpected_credential_type";
const invalidAssertion = "invalid_assertion";
const invalidClientCredential = "invalid_client_credential";
const tokenRefreshRequired = "token_refresh_required";
const userTimeoutReached = "user_timeout_reached";
const tokenClaimsCnfRequiredForSignedJwt = "token_claims_cnf_required_for_signedjwt";
const authorizationCodeMissingFromServerResponse = "authorization_code_missing_from_server_response";
const bindingKeyNotRemoved = "binding_key_not_removed";
const endSessionEndpointNotSupported = "end_session_endpoint_not_supported";
const keyIdMissing = "key_id_missing";
const noNetworkConnectivity = "no_network_connectivity";
const userCanceled = "user_canceled";
const missingTenantIdError = "missing_tenant_id_error";
const methodNotImplemented = "method_not_implemented";
const nestedAppAuthBridgeDisabled = "nested_app_auth_bridge_disabled";

/*! @azure/msal-common v15.8.1 2025-07-08 */

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * ClientAuthErrorMessage class containing string constants used by error codes and messages.
 */
const ClientAuthErrorMessages = {
    [clientInfoDecodingError]: "The client info could not be parsed/decoded correctly",
    [clientInfoEmptyError]: "The client info was empty",
    [tokenParsingError]: "Token cannot be parsed",
    [nullOrEmptyToken]: "The token is null or empty",
    [endpointResolutionError]: "Endpoints cannot be resolved",
    [networkError]: "Network request failed",
    [openIdConfigError]: "Could not retrieve endpoints. Check your authority and verify the .well-known/openid-configuration endpoint returns the required endpoints.",
    [hashNotDeserialized]: "The hash parameters could not be deserialized",
    [invalidState]: "State was not the expected format",
    [stateMismatch]: "State mismatch error",
    [stateNotFound]: "State not found",
    [nonceMismatch]: "Nonce mismatch error",
    [authTimeNotFound]: "Max Age was requested and the ID token is missing the auth_time variable." +
        " auth_time is an optional claim and is not enabled by default - it must be enabled." +
        " See https://aka.ms/msaljs/optional-claims for more information.",
    [maxAgeTranspired]: "Max Age is set to 0, or too much time has elapsed since the last end-user authentication.",
    [multipleMatchingTokens]: "The cache contains multiple tokens satisfying the requirements. " +
        "Call AcquireToken again providing more requirements such as authority or account.",
    [multipleMatchingAccounts]: "The cache contains multiple accounts satisfying the given parameters. Please pass more info to obtain the correct account",
    [multipleMatchingAppMetadata]: "The cache contains multiple appMetadata satisfying the given parameters. Please pass more info to obtain the correct appMetadata",
    [requestCannotBeMade]: "Token request cannot be made without authorization code or refresh token.",
    [cannotRemoveEmptyScope]: "Cannot remove null or empty scope from ScopeSet",
    [cannotAppendScopeSet]: "Cannot append ScopeSet",
    [emptyInputScopeSet]: "Empty input ScopeSet cannot be processed",
    [deviceCodePollingCancelled]: "Caller has cancelled token endpoint polling during device code flow by setting DeviceCodeRequest.cancel = true.",
    [deviceCodeExpired]: "Device code is expired.",
    [deviceCodeUnknownError]: "Device code stopped polling for unknown reasons.",
    [noAccountInSilentRequest]: "Please pass an account object, silent flow is not supported without account information",
    [invalidCacheRecord]: "Cache record object was null or undefined.",
    [invalidCacheEnvironment]: "Invalid environment when attempting to create cache entry",
    [noAccountFound]: "No account found in cache for given key.",
    [noCryptoObject]: "No crypto object detected.",
    [unexpectedCredentialType]: "Unexpected credential type.",
    [invalidAssertion]: "Client assertion must meet requirements described in https://tools.ietf.org/html/rfc7515",
    [invalidClientCredential]: "Client credential (secret, certificate, or assertion) must not be empty when creating a confidential client. An application should at most have one credential",
    [tokenRefreshRequired]: "Cannot return token from cache because it must be refreshed. This may be due to one of the following reasons: forceRefresh parameter is set to true, claims have been requested, there is no cached access token or it is expired.",
    [userTimeoutReached]: "User defined timeout for device code polling reached",
    [tokenClaimsCnfRequiredForSignedJwt]: "Cannot generate a POP jwt if the token_claims are not populated",
    [authorizationCodeMissingFromServerResponse]: "Server response does not contain an authorization code to proceed",
    [bindingKeyNotRemoved]: "Could not remove the credential's binding key from storage.",
    [endSessionEndpointNotSupported]: "The provided authority does not support logout",
    [keyIdMissing]: "A keyId value is missing from the requested bound token's cache record and is required to match the token to it's stored binding key.",
    [noNetworkConnectivity]: "No network connectivity. Check your internet connection.",
    [userCanceled]: "User cancelled the flow.",
    [missingTenantIdError]: "A tenant id - not common, organizations, or consumers - must be specified when using the client_credentials flow.",
    [methodNotImplemented]: "This method has not been implemented",
    [nestedAppAuthBridgeDisabled]: "The nested app auth bridge is disabled",
};
/**
 * Error thrown when there is an error in the client code running on the browser.
 */
class ClientAuthError extends AuthError {
    constructor(errorCode, additionalMessage) {
        super(errorCode, additionalMessage
            ? `${ClientAuthErrorMessages[errorCode]}: ${additionalMessage}`
            : ClientAuthErrorMessages[errorCode]);
        this.name = "ClientAuthError";
        Object.setPrototypeOf(this, ClientAuthError.prototype);
    }
}
function createClientAuthError(errorCode, additionalMessage) {
    return new ClientAuthError(errorCode, additionalMessage);
}

/*! @azure/msal-common v15.8.1 2025-07-08 */

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Log message level.
 */
var LogLevel;
(function (LogLevel) {
    LogLevel[LogLevel["Error"] = 0] = "Error";
    LogLevel[LogLevel["Warning"] = 1] = "Warning";
    LogLevel[LogLevel["Info"] = 2] = "Info";
    LogLevel[LogLevel["Verbose"] = 3] = "Verbose";
    LogLevel[LogLevel["Trace"] = 4] = "Trace";
})(LogLevel || (LogLevel = {}));
/**
 * Class which facilitates logging of messages to a specific place.
 */
class Logger {
    constructor(loggerOptions, packageName, packageVersion) {
        // Current log level, defaults to info.
        this.level = LogLevel.Info;
        const defaultLoggerCallback = () => {
            return;
        };
        const setLoggerOptions = loggerOptions || Logger.createDefaultLoggerOptions();
        this.localCallback =
            setLoggerOptions.loggerCallback || defaultLoggerCallback;
        this.piiLoggingEnabled = setLoggerOptions.piiLoggingEnabled || false;
        this.level =
            typeof setLoggerOptions.logLevel === "number"
                ? setLoggerOptions.logLevel
                : LogLevel.Info;
        this.correlationId =
            setLoggerOptions.correlationId || Constants.EMPTY_STRING;
        this.packageName = packageName || Constants.EMPTY_STRING;
        this.packageVersion = packageVersion || Constants.EMPTY_STRING;
    }
    static createDefaultLoggerOptions() {
        return {
            loggerCallback: () => {
                // allow users to not set loggerCallback
            },
            piiLoggingEnabled: false,
            logLevel: LogLevel.Info,
        };
    }
    /**
     * Create new Logger with existing configurations.
     */
    clone(packageName, packageVersion, correlationId) {
        return new Logger({
            loggerCallback: this.localCallback,
            piiLoggingEnabled: this.piiLoggingEnabled,
            logLevel: this.level,
            correlationId: correlationId || this.correlationId,
        }, packageName, packageVersion);
    }
    /**
     * Log message with required options.
     */
    logMessage(logMessage, options) {
        if (options.logLevel > this.level ||
            (!this.piiLoggingEnabled && options.containsPii)) {
            return;
        }
        const timestamp = new Date().toUTCString();
        // Add correlationId to logs if set, correlationId provided on log messages take precedence
        const logHeader = `[${timestamp}] : [${options.correlationId || this.correlationId || ""}]`;
        const log = `${logHeader} : ${this.packageName}@${this.packageVersion} : ${LogLevel[options.logLevel]} - ${logMessage}`;
        // debug(`msal:${LogLevel[options.logLevel]}${options.containsPii ? "-Pii": Constants.EMPTY_STRING}${options.context ? `:${options.context}` : Constants.EMPTY_STRING}`)(logMessage);
        this.executeCallback(options.logLevel, log, options.containsPii || false);
    }
    /**
     * Execute callback with message.
     */
    executeCallback(level, message, containsPii) {
        if (this.localCallback) {
            this.localCallback(level, message, containsPii);
        }
    }
    /**
     * Logs error messages.
     */
    error(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Error,
            containsPii: false,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Logs error messages with PII.
     */
    errorPii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Error,
            containsPii: true,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Logs warning messages.
     */
    warning(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Warning,
            containsPii: false,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Logs warning messages with PII.
     */
    warningPii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Warning,
            containsPii: true,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Logs info messages.
     */
    info(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Info,
            containsPii: false,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Logs info messages with PII.
     */
    infoPii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Info,
            containsPii: true,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Logs verbose messages.
     */
    verbose(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Verbose,
            containsPii: false,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Logs verbose messages with PII.
     */
    verbosePii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Verbose,
            containsPii: true,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Logs trace messages.
     */
    trace(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Trace,
            containsPii: false,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Logs trace messages with PII.
     */
    tracePii(message, correlationId) {
        this.logMessage(message, {
            logLevel: LogLevel.Trace,
            containsPii: true,
            correlationId: correlationId || Constants.EMPTY_STRING,
        });
    }
    /**
     * Returns whether PII Logging is enabled or not.
     */
    isPiiLoggingEnabled() {
        return this.piiLoggingEnabled || false;
    }
}

/*! @azure/msal-common v15.8.1 2025-07-08 */
/**
 * Convert seconds to JS Date object. Seconds can be in a number or string format or undefined (will still return a date).
 * @param seconds
 */
function toDateFromSeconds(seconds) {
    if (seconds) {
        return new Date(Number(seconds) * 1000);
    }
    return new Date();
}

/*! @azure/msal-common v15.8.1 2025-07-08 */
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const redirectUriEmpty = "redirect_uri_empty";
const claimsRequestParsingError = "claims_request_parsing_error";
const authorityUriInsecure = "authority_uri_insecure";
const urlParseError = "url_parse_error";
const urlEmptyError = "empty_url_error";
const emptyInputScopesError = "empty_input_scopes_error";
const invalidClaims = "invalid_claims";
const tokenRequestEmpty = "token_request_empty";
const logoutRequestEmpty = "logout_request_empty";
const invalidCodeChallengeMethod = "invalid_code_challenge_method";
const pkceParamsMissing = "pkce_params_missing";
const invalidCloudDiscoveryMetadata = "invalid_cloud_discovery_metadata";
const invalidAuthorityMetadata = "invalid_authority_metadata";
const untrustedAuthority = "untrusted_authority";
const missingSshJwk = "missing_ssh_jwk";
const missingSshKid = "missing_ssh_kid";
const missingNonceAuthenticationHeader = "missing_nonce_authentication_header";
const invalidAuthenticationHeader = "invalid_authentication_header";
const cannotSetOIDCOptions = "cannot_set_OIDCOptions";
const cannotAllowPlatformBroker = "cannot_allow_platform_broker";
const authorityMismatch = "authority_mismatch";

/*! @azure/msal-common v15.8.1 2025-07-08 */

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const ClientConfigurationErrorMessages = {
    [redirectUriEmpty]: "A redirect URI is required for all calls, and none has been set.",
    [claimsRequestParsingError]: "Could not parse the given claims request object.",
    [authorityUriInsecure]: "Authority URIs must use https.  Please see here for valid authority configuration options: https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-js-initializing-client-applications#configuration-options",
    [urlParseError]: "URL could not be parsed into appropriate segments.",
    [urlEmptyError]: "URL was empty or null.",
    [emptyInputScopesError]: "Scopes cannot be passed as null, undefined or empty array because they are required to obtain an access token.",
    [invalidClaims]: "Given claims parameter must be a stringified JSON object.",
    [tokenRequestEmpty]: "Token request was empty and not found in cache.",
    [logoutRequestEmpty]: "The logout request was null or undefined.",
    [invalidCodeChallengeMethod]: 'code_challenge_method passed is invalid. Valid values are "plain" and "S256".',
    [pkceParamsMissing]: "Both params: code_challenge and code_challenge_method are to be passed if to be sent in the request",
    [invalidCloudDiscoveryMetadata]: "Invalid cloudDiscoveryMetadata provided. Must be a stringified JSON object containing tenant_discovery_endpoint and metadata fields",
    [invalidAuthorityMetadata]: "Invalid authorityMetadata provided. Must by a stringified JSON object containing authorization_endpoint, token_endpoint, issuer fields.",
    [untrustedAuthority]: "The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter.",
    [missingSshJwk]: "Missing sshJwk in SSH certificate request. A stringified JSON Web Key is required when using the SSH authentication scheme.",
    [missingSshKid]: "Missing sshKid in SSH certificate request. A string that uniquely identifies the public SSH key is required when using the SSH authentication scheme.",
    [missingNonceAuthenticationHeader]: "Unable to find an authentication header containing server nonce. Either the Authentication-Info or WWW-Authenticate headers must be present in order to obtain a server nonce.",
    [invalidAuthenticationHeader]: "Invalid authentication header provided",
    [cannotSetOIDCOptions]: "Cannot set OIDCOptions parameter. Please change the protocol mode to OIDC or use a non-Microsoft authority.",
    [cannotAllowPlatformBroker]: "Cannot set allowPlatformBroker parameter to true when not in AAD protocol mode.",
    [authorityMismatch]: "Authority mismatch error. Authority provided in login request or PublicClientApplication config does not match the environment of the provided account. Please use a matching account or make an interactive request to login to this authority.",
};
/**
 * Error thrown when there is an error in configuration of the MSAL.js library.
 */
class ClientConfigurationError extends AuthError {
    constructor(errorCode) {
        super(errorCode, ClientConfigurationErrorMessages[errorCode]);
        this.name = "ClientConfigurationError";
        Object.setPrototypeOf(this, ClientConfigurationError.prototype);
    }
}
function createClientConfigurationError(errorCode) {
    return new ClientConfigurationError(errorCode);
}

/*! @azure/msal-common v15.8.1 2025-07-08 */
const X_CLIENT_EXTRA_SKU = "x-client-xtra-sku";

/*! @azure/msal-common v15.8.1 2025-07-08 */

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Error thrown when there is an error with the server code, for example, unavailability.
 */
class ServerError extends AuthError {
    constructor(errorCode, errorMessage, subError, errorNo, status) {
        super(errorCode, errorMessage, subError);
        this.name = "ServerError";
        this.errorNo = errorNo;
        this.status = status;
        Object.setPrototypeOf(this, ServerError.prototype);
    }
}

/*! @azure/msal-common v15.8.1 2025-07-08 */
/**
 * Error thrown when user interaction is required.
 */
class InteractionRequiredAuthError extends AuthError {
    constructor(errorCode, errorMessage, subError, timestamp, traceId, correlationId, claims, errorNo) {
        super(errorCode, errorMessage, subError);
        Object.setPrototypeOf(this, InteractionRequiredAuthError.prototype);
        this.timestamp = timestamp || Constants.EMPTY_STRING;
        this.traceId = traceId || Constants.EMPTY_STRING;
        this.correlationId = correlationId || Constants.EMPTY_STRING;
        this.claims = claims || Constants.EMPTY_STRING;
        this.name = "InteractionRequiredAuthError";
        this.errorNo = errorNo;
    }
}

/*! @azure/msal-common v15.8.1 2025-07-08 */

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const skuGroupSeparator = ",";
const skuValueSeparator = "|";
function makeExtraSkuString(params) {
    const { skus, libraryName, libraryVersion, extensionName, extensionVersion, } = params;
    const skuMap = new Map([
        [0, [libraryName, libraryVersion]],
        [2, [extensionName, extensionVersion]],
    ]);
    let skuArr = [];
    if (skus?.length) {
        skuArr = skus.split(skuGroupSeparator);
        // Ignore invalid input sku param
        if (skuArr.length < 4) {
            return skus;
        }
    }
    else {
        skuArr = Array.from({ length: 4 }, () => skuValueSeparator);
    }
    skuMap.forEach((value, key) => {
        if (value.length === 2 && value[0]?.length && value[1]?.length) {
            setSku({
                skuArr,
                index: key,
                skuName: value[0],
                skuVersion: value[1],
            });
        }
    });
    return skuArr.join(skuGroupSeparator);
}
function setSku(params) {
    const { skuArr, index, skuName, skuVersion } = params;
    if (index >= skuArr.length) {
        return;
    }
    skuArr[index] = [skuName, skuVersion].join(skuValueSeparator);
}
/** @internal */
class ServerTelemetryManager {
    constructor(telemetryRequest, cacheManager) {
        this.cacheOutcome = CacheOutcome.NOT_APPLICABLE;
        this.cacheManager = cacheManager;
        this.apiId = telemetryRequest.apiId;
        this.correlationId = telemetryRequest.correlationId;
        this.wrapperSKU = telemetryRequest.wrapperSKU || Constants.EMPTY_STRING;
        this.wrapperVer = telemetryRequest.wrapperVer || Constants.EMPTY_STRING;
        this.telemetryCacheKey =
            SERVER_TELEM_CONSTANTS.CACHE_KEY +
                Separators.CACHE_KEY_SEPARATOR +
                telemetryRequest.clientId;
    }
    /**
     * API to add MSER Telemetry to request
     */
    generateCurrentRequestHeaderValue() {
        const request = `${this.apiId}${SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR}${this.cacheOutcome}`;
        const platformFieldsArr = [this.wrapperSKU, this.wrapperVer];
        const nativeBrokerErrorCode = this.getNativeBrokerErrorCode();
        if (nativeBrokerErrorCode?.length) {
            platformFieldsArr.push(`broker_error=${nativeBrokerErrorCode}`);
        }
        const platformFields = platformFieldsArr.join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
        const regionDiscoveryFields = this.getRegionDiscoveryFields();
        const requestWithRegionDiscoveryFields = [
            request,
            regionDiscoveryFields,
        ].join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
        return [
            SERVER_TELEM_CONSTANTS.SCHEMA_VERSION,
            requestWithRegionDiscoveryFields,
            platformFields,
        ].join(SERVER_TELEM_CONSTANTS.CATEGORY_SEPARATOR);
    }
    /**
     * API to add MSER Telemetry for the last failed request
     */
    generateLastRequestHeaderValue() {
        const lastRequests = this.getLastRequests();
        const maxErrors = ServerTelemetryManager.maxErrorsToSend(lastRequests);
        const failedRequests = lastRequests.failedRequests
            .slice(0, 2 * maxErrors)
            .join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
        const errors = lastRequests.errors
            .slice(0, maxErrors)
            .join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
        const errorCount = lastRequests.errors.length;
        // Indicate whether this header contains all data or partial data
        const overflow = maxErrors < errorCount
            ? SERVER_TELEM_CONSTANTS.OVERFLOW_TRUE
            : SERVER_TELEM_CONSTANTS.OVERFLOW_FALSE;
        const platformFields = [errorCount, overflow].join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
        return [
            SERVER_TELEM_CONSTANTS.SCHEMA_VERSION,
            lastRequests.cacheHits,
            failedRequests,
            errors,
            platformFields,
        ].join(SERVER_TELEM_CONSTANTS.CATEGORY_SEPARATOR);
    }
    /**
     * API to cache token failures for MSER data capture
     * @param error
     */
    cacheFailedRequest(error) {
        const lastRequests = this.getLastRequests();
        if (lastRequests.errors.length >=
            SERVER_TELEM_CONSTANTS.MAX_CACHED_ERRORS) {
            // Remove a cached error to make room, first in first out
            lastRequests.failedRequests.shift(); // apiId
            lastRequests.failedRequests.shift(); // correlationId
            lastRequests.errors.shift();
        }
        lastRequests.failedRequests.push(this.apiId, this.correlationId);
        if (error instanceof Error && !!error && error.toString()) {
            if (error instanceof AuthError) {
                if (error.subError) {
                    lastRequests.errors.push(error.subError);
                }
                else if (error.errorCode) {
                    lastRequests.errors.push(error.errorCode);
                }
                else {
                    lastRequests.errors.push(error.toString());
                }
            }
            else {
                lastRequests.errors.push(error.toString());
            }
        }
        else {
            lastRequests.errors.push(SERVER_TELEM_CONSTANTS.UNKNOWN_ERROR);
        }
        this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId);
        return;
    }
    /**
     * Update server telemetry cache entry by incrementing cache hit counter
     */
    incrementCacheHits() {
        const lastRequests = this.getLastRequests();
        lastRequests.cacheHits += 1;
        this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId);
        return lastRequests.cacheHits;
    }
    /**
     * Get the server telemetry entity from cache or initialize a new one
     */
    getLastRequests() {
        const initialValue = {
            failedRequests: [],
            errors: [],
            cacheHits: 0,
        };
        const lastRequests = this.cacheManager.getServerTelemetry(this.telemetryCacheKey);
        return lastRequests || initialValue;
    }
    /**
     * Remove server telemetry cache entry
     */
    clearTelemetryCache() {
        const lastRequests = this.getLastRequests();
        const numErrorsFlushed = ServerTelemetryManager.maxErrorsToSend(lastRequests);
        const errorCount = lastRequests.errors.length;
        if (numErrorsFlushed === errorCount) {
            // All errors were sent on last request, clear Telemetry cache
            this.cacheManager.removeItem(this.telemetryCacheKey, this.correlationId);
        }
        else {
            // Partial data was flushed to server, construct a new telemetry cache item with errors that were not flushed
            const serverTelemEntity = {
                failedRequests: lastRequests.failedRequests.slice(numErrorsFlushed * 2),
                errors: lastRequests.errors.slice(numErrorsFlushed),
                cacheHits: 0,
            };
            this.cacheManager.setServerTelemetry(this.telemetryCacheKey, serverTelemEntity, this.correlationId);
        }
    }
    /**
     * Returns the maximum number of errors that can be flushed to the server in the next network request
     * @param serverTelemetryEntity
     */
    static maxErrorsToSend(serverTelemetryEntity) {
        let i;
        let maxErrors = 0;
        let dataSize = 0;
        const errorCount = serverTelemetryEntity.errors.length;
        for (i = 0; i < errorCount; i++) {
            // failedRequests parameter contains pairs of apiId and correlationId, multiply index by 2 to preserve pairs
            const apiId = serverTelemetryEntity.failedRequests[2 * i] ||
                Constants.EMPTY_STRING;
            const correlationId = serverTelemetryEntity.failedRequests[2 * i + 1] ||
                Constants.EMPTY_STRING;
            const errorCode = serverTelemetryEntity.errors[i] || Constants.EMPTY_STRING;
            // Count number of characters that would be added to header, each character is 1 byte. Add 3 at the end to account for separators
            dataSize +=
                apiId.toString().length +
                    correlationId.toString().length +
                    errorCode.length +
                    3;
            if (dataSize < SERVER_TELEM_CONSTANTS.MAX_LAST_HEADER_BYTES) {
                // Adding this entry to the header would still keep header size below the limit
                maxErrors += 1;
            }
            else {
                break;
            }
        }
        return maxErrors;
    }
    /**
     * Get the region discovery fields
     *
     * @returns string
     */
    getRegionDiscoveryFields() {
        const regionDiscoveryFields = [];
        regionDiscoveryFields.push(this.regionUsed || Constants.EMPTY_STRING);
        regionDiscoveryFields.push(this.regionSource || Constants.EMPTY_STRING);
        regionDiscoveryFields.push(this.regionOutcome || Constants.EMPTY_STRING);
        return regionDiscoveryFields.join(",");
    }
    /**
     * Update the region discovery metadata
     *
     * @param regionDiscoveryMetadata
     * @returns void
     */
    updateRegionDiscoveryMetadata(regionDiscoveryMetadata) {
        this.regionUsed = regionDiscoveryMetadata.region_used;
        this.regionSource = regionDiscoveryMetadata.region_source;
        this.regionOutcome = regionDiscoveryMetadata.region_outcome;
    }
    /**
     * Set cache outcome
     */
    setCacheOutcome(cacheOutcome) {
        this.cacheOutcome = cacheOutcome;
    }
    setNativeBrokerErrorCode(errorCode) {
        const lastRequests = this.getLastRequests();
        lastRequests.nativeBrokerErrorCode = errorCode;
        this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId);
    }
    getNativeBrokerErrorCode() {
        return this.getLastRequests().nativeBrokerErrorCode;
    }
    clearNativeBrokerErrorCode() {
        const lastRequests = this.getLastRequests();
        delete lastRequests.nativeBrokerErrorCode;
        this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId);
    }
    static makeExtraSkuString(params) {
        return makeExtraSkuString(params);
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
class BasePersistence {
    async verifyPersistence() {
        // We are using a different location for the test to avoid overriding the functional cache
        const persistenceValidator = await this.createForPersistenceValidation();
        try {
            await persistenceValidator.save(Constants$1.PERSISTENCE_TEST_DATA);
            const retrievedDummyData = await persistenceValidator.load();
            if (!retrievedDummyData) {
                throw PersistenceError.createCachePersistenceError("Persistence check failed. Data was written but it could not be read. " +
                    "Possible cause: on Linux, LibSecret is installed but D-Bus isn't running \
                    because it cannot be started over SSH.");
            }
            if (retrievedDummyData !== Constants$1.PERSISTENCE_TEST_DATA) {
                throw PersistenceError.createCachePersistenceError(`Persistence check failed. Data written ${Constants$1.PERSISTENCE_TEST_DATA} is different \
                    from data read ${retrievedDummyData}`);
            }
            await persistenceValidator.delete();
            return true;
        }
        catch (e) {
            throw PersistenceError.createCachePersistenceError(`Verifing persistence failed with the error: ${e}`);
        }
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Reads and writes data to file specified by file location. File contents are not
 * encrypted.
 *
 * If file or directory has not been created, it FilePersistence.create() will create
 * file and any directories in the path recursively.
 */
class FilePersistence extends BasePersistence {
    constructor(fileLocation, loggerOptions) {
        super();
        this.logger = new Logger(loggerOptions || FilePersistence.createDefaultLoggerOptions());
        this.filePath = fileLocation;
    }
    static async create(fileLocation, loggerOptions) {
        const filePersistence = new FilePersistence(fileLocation, loggerOptions);
        await filePersistence.createCacheFile();
        return filePersistence;
    }
    async save(contents) {
        try {
            await fs.promises.writeFile(this.getFilePath(), contents, "utf-8");
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
            }
            else {
                throw err;
            }
        }
    }
    async saveBuffer(contents) {
        try {
            await fs.promises.writeFile(this.getFilePath(), contents);
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
            }
            else {
                throw err;
            }
        }
    }
    async load() {
        try {
            return await fs.promises.readFile(this.getFilePath(), "utf-8");
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
            }
            else {
                throw err;
            }
        }
    }
    async loadBuffer() {
        try {
            return await fs.promises.readFile(this.getFilePath());
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
            }
            else {
                throw err;
            }
        }
    }
    async delete() {
        try {
            await fs.promises.unlink(this.getFilePath());
            return true;
        }
        catch (err) {
            if (isNodeError(err)) {
                if (err.code === Constants$1.ENOENT_ERROR) {
                    // file does not exist, so it was not deleted
                    this.logger.warning("Cache file does not exist, so it could not be deleted");
                    return false;
                }
                throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
            }
            else {
                throw err;
            }
        }
    }
    getFilePath() {
        return this.filePath;
    }
    async reloadNecessary(lastSync) {
        return lastSync < (await this.timeLastModified());
    }
    getLogger() {
        return this.logger;
    }
    createForPersistenceValidation() {
        const testCacheFileLocation = `${path.dirname(this.filePath)}/test.cache`;
        return FilePersistence.create(testCacheFileLocation);
    }
    static createDefaultLoggerOptions() {
        return {
            loggerCallback: () => {
                // allow users to not set loggerCallback
            },
            piiLoggingEnabled: false,
            logLevel: LogLevel.Info,
        };
    }
    async timeLastModified() {
        try {
            const stats = await fs.promises.stat(this.filePath);
            return stats.mtime.getTime();
        }
        catch (err) {
            if (isNodeError(err)) {
                if (err.code === Constants$1.ENOENT_ERROR) {
                    // file does not exist, so it's never been modified
                    this.logger.verbose("Cache file does not exist");
                    return 0;
                }
                throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
            }
            else {
                throw err;
            }
        }
    }
    async createCacheFile() {
        await this.createFileDirectory();
        // File is created only if it does not exist
        const fileHandle = await fs.promises.open(this.filePath, "a");
        await fileHandle.close();
        this.logger.info(`File created at ${this.filePath}`);
    }
    async createFileDirectory() {
        try {
            await fs.promises.mkdir(path.dirname(this.filePath), { recursive: true });
        }
        catch (err) {
            if (isNodeError(err)) {
                if (err.code === Constants$1.EEXIST_ERROR) {
                    this.logger.info(`Directory ${path.dirname(this.filePath)}  already exists`);
                }
                else {
                    throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
                }
            }
            else {
                throw err;
            }
        }
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
class UnavailableDpapi {
    constructor(errorMessage) {
        this.errorMessage = errorMessage;
    }
    protectData() {
        throw new Error(this.errorMessage);
    }
    unprotectData() {
        throw new Error(this.errorMessage);
    }
}
let Dpapi;
if (process.platform !== "win32") {
    Dpapi = new UnavailableDpapi("Dpapi is not supported on this platform");
}
else {
    // In .mjs files, require is not defined. We need to use createRequire to get a require function
    const safeRequire = typeof require !== "undefined"
        ? require
        : module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('msal-node-extensions.cjs', document.baseURI).href)));
    try {
        Dpapi = safeRequire(`../bin/${process.arch}/dpapi`);
    }
    catch (e) {
        Dpapi = new UnavailableDpapi("Dpapi bindings unavailable");
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Specifies the scope of the data protection - either the current user or the local
 * machine.
 *
 * You do not need a key to protect or unprotect the data.
 * If you set the Scope to CurrentUser, only applications running on your credentials can
 * unprotect the data; however, that means that any application running on your credentials
 * can access the protected data. If you set the Scope to LocalMachine, any full-trust
 * application on the computer can unprotect, access, and modify the data.
 *
 */
const DataProtectionScope = {
    CurrentUser: "CurrentUser",
    LocalMachine: "LocalMachine",
};

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Uses CryptProtectData and CryptUnprotectData on Windows to encrypt and decrypt file contents.
 *
 * scope: Scope of the data protection. Either local user or the current machine
 * optionalEntropy: Password or other additional entropy used to encrypt the data
 */
class FilePersistenceWithDataProtection extends BasePersistence {
    constructor(filePersistence, scope, optionalEntropy) {
        super();
        this.scope = scope;
        this.optionalEntropy = optionalEntropy
            ? Buffer.from(optionalEntropy, "utf-8")
            : null;
        this.filePersistence = filePersistence;
    }
    static async create(fileLocation, scope, optionalEntropy, loggerOptions) {
        const filePersistence = await FilePersistence.create(fileLocation, loggerOptions);
        const persistence = new FilePersistenceWithDataProtection(filePersistence, scope, optionalEntropy);
        return persistence;
    }
    async save(contents) {
        try {
            const encryptedContents = Dpapi.protectData(Buffer.from(contents, "utf-8"), this.optionalEntropy, this.scope.toString());
            await this.filePersistence.saveBuffer(encryptedContents);
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createFilePersistenceWithDPAPIError(err.message);
            }
            else {
                throw err;
            }
        }
    }
    async load() {
        try {
            const encryptedContents = await this.filePersistence.loadBuffer();
            if (typeof encryptedContents === "undefined" ||
                !encryptedContents ||
                0 === encryptedContents.length) {
                this.filePersistence
                    .getLogger()
                    .info("Encrypted contents loaded from file were null or empty");
                return null;
            }
            return Dpapi.unprotectData(encryptedContents, this.optionalEntropy, this.scope.toString()).toString();
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createFilePersistenceWithDPAPIError(err.message);
            }
            else {
                throw err;
            }
        }
    }
    async delete() {
        return this.filePersistence.delete();
    }
    async reloadNecessary(lastSync) {
        return this.filePersistence.reloadNecessary(lastSync);
    }
    getFilePath() {
        return this.filePersistence.getFilePath();
    }
    getLogger() {
        return this.filePersistence.getLogger();
    }
    createForPersistenceValidation() {
        const testCacheFileLocation = `${path.dirname(this.filePersistence.getFilePath())}/test.cache`;
        return FilePersistenceWithDataProtection.create(testCacheFileLocation, DataProtectionScope.CurrentUser);
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Uses reads and writes passwords to macOS keychain
 *
 * serviceName: Identifier used as key for whatever value is stored
 * accountName: Account under which password should be stored
 */
class KeychainPersistence extends BasePersistence {
    constructor(filePersistence, serviceName, accountName) {
        super();
        this.filePersistence = filePersistence;
        this.serviceName = serviceName;
        this.accountName = accountName;
    }
    static async create(fileLocation, serviceName, accountName, loggerOptions) {
        const filePersistence = await FilePersistence.create(fileLocation, loggerOptions);
        const persistence = new KeychainPersistence(filePersistence, serviceName, accountName);
        return persistence;
    }
    async save(contents) {
        try {
            await keytar.setPassword(this.serviceName, this.accountName, contents);
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createKeychainPersistenceError(err.message);
            }
            else {
                throw err;
            }
        }
        // Write dummy data to update file mtime
        await this.filePersistence.save("{}");
    }
    async load() {
        try {
            return await keytar.getPassword(this.serviceName, this.accountName);
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createKeychainPersistenceError(err.message);
            }
            else {
                throw err;
            }
        }
    }
    async delete() {
        try {
            await this.filePersistence.delete();
            return await keytar.deletePassword(this.serviceName, this.accountName);
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createKeychainPersistenceError(err.message);
            }
            else {
                throw err;
            }
        }
    }
    async reloadNecessary(lastSync) {
        return this.filePersistence.reloadNecessary(lastSync);
    }
    getFilePath() {
        return this.filePersistence.getFilePath();
    }
    getLogger() {
        return this.filePersistence.getLogger();
    }
    createForPersistenceValidation() {
        const testCacheFileLocation = `${path.dirname(this.filePersistence.getFilePath())}/test.cache`;
        return KeychainPersistence.create(testCacheFileLocation, "persistenceValidationServiceName", "persistencValidationAccountName");
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Uses reads and writes passwords to Secret Service API/libsecret. Requires libsecret
 * to be installed.
 *
 * serviceName: Identifier used as key for whatever value is stored
 * accountName: Account under which password should be stored
 */
class LibSecretPersistence extends BasePersistence {
    constructor(filePersistence, serviceName, accountName) {
        super();
        this.filePersistence = filePersistence;
        this.serviceName = serviceName;
        this.accountName = accountName;
    }
    static async create(fileLocation, serviceName, accountName, loggerOptions) {
        const filePersistence = await FilePersistence.create(fileLocation, loggerOptions);
        const persistence = new LibSecretPersistence(filePersistence, serviceName, accountName);
        return persistence;
    }
    async save(contents) {
        try {
            await keytar.setPassword(this.serviceName, this.accountName, contents);
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createLibSecretError(err.message);
            }
            else {
                throw err;
            }
        }
        // Write dummy data to update file mtime
        await this.filePersistence.save("{}");
    }
    async load() {
        try {
            return await keytar.getPassword(this.serviceName, this.accountName);
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createLibSecretError(err.message);
            }
            else {
                throw err;
            }
        }
    }
    async delete() {
        try {
            await this.filePersistence.delete();
            return await keytar.deletePassword(this.serviceName, this.accountName);
        }
        catch (err) {
            if (isNodeError(err)) {
                throw PersistenceError.createLibSecretError(err.message);
            }
            else {
                throw err;
            }
        }
    }
    async reloadNecessary(lastSync) {
        return this.filePersistence.reloadNecessary(lastSync);
    }
    getFilePath() {
        return this.filePersistence.getFilePath();
    }
    getLogger() {
        return this.filePersistence.getLogger();
    }
    createForPersistenceValidation() {
        const testCacheFileLocation = `${path.dirname(this.filePersistence.getFilePath())}/test.cache`;
        return LibSecretPersistence.create(testCacheFileLocation, "persistenceValidationServiceName", "persistencValidationAccountName");
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
class Environment {
    static get homeEnvVar() {
        return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.HOME);
    }
    static get lognameEnvVar() {
        return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.LOGNAME);
    }
    static get userEnvVar() {
        return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.USER);
    }
    static get lnameEnvVar() {
        return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.LNAME);
    }
    static get usernameEnvVar() {
        return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.USERNAME);
    }
    static getEnvironmentVariable(name) {
        return process.env[name] || "";
    }
    static getEnvironmentPlatform() {
        return process.platform;
    }
    static isWindowsPlatform() {
        return this.getEnvironmentPlatform() === Platform.WINDOWS;
    }
    static isLinuxPlatform() {
        return this.getEnvironmentPlatform() === Platform.LINUX;
    }
    static isMacPlatform() {
        return this.getEnvironmentPlatform() === Platform.MACOS;
    }
    static isLinuxRootUser() {
        if (typeof process.getuid !== "function") {
            return false;
        }
        return process.getuid() === Constants$1.LINUX_ROOT_USER_GUID;
    }
    static getUserRootDirectory() {
        return !this.isWindowsPlatform()
            ? this.getUserHomeDirOnUnix()
            : this.getUserHomeDirOnWindows();
    }
    static getUserHomeDirOnWindows() {
        return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.LOCAL_APPLICATION_DATA);
    }
    static getUserHomeDirOnUnix() {
        if (this.isWindowsPlatform()) {
            throw PersistenceError.createNotSupportedError("Getting the user home directory for unix is not supported in windows");
        }
        if (this.homeEnvVar) {
            return this.homeEnvVar;
        }
        let username = null;
        if (this.lognameEnvVar) {
            username = this.lognameEnvVar;
        }
        else if (this.userEnvVar) {
            username = this.userEnvVar;
        }
        else if (this.lnameEnvVar) {
            username = this.lnameEnvVar;
        }
        else if (this.usernameEnvVar) {
            username = this.usernameEnvVar;
        }
        if (this.isMacPlatform()) {
            return username ? path.join("/Users", username) : null;
        }
        else if (this.isLinuxPlatform()) {
            if (this.isLinuxRootUser()) {
                return "/root";
            }
            else {
                return username ? path.join("/home", username) : null;
            }
        }
        else {
            throw PersistenceError.createNotSupportedError("Getting the user home directory for unix is not supported in windows");
        }
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
class PersistenceCreator {
    static async createPersistence(config) {
        let peristence;
        // On Windows, uses a DPAPI encrypted file
        if (Environment.isWindowsPlatform()) {
            if (!config.cachePath || !config.dataProtectionScope) {
                throw PersistenceError.createPersistenceNotValidatedError("Cache path and/or data protection scope not provided for the FilePersistenceWithDataProtection cache plugin");
            }
            peristence = await FilePersistenceWithDataProtection.create(config.cachePath, DataProtectionScope.CurrentUser, undefined, config.loggerOptions);
        }
        // On Mac, uses keychain.
        else if (Environment.isMacPlatform()) {
            if (!config.cachePath ||
                !config.serviceName ||
                !config.accountName) {
                throw PersistenceError.createPersistenceNotValidatedError("Cache path, service name and/or account name not provided for the KeychainPersistence cache plugin");
            }
            peristence = await KeychainPersistence.create(config.cachePath, config.serviceName, config.accountName, config.loggerOptions);
        }
        // On Linux, uses  libsecret to store to secret service. Libsecret has to be installed.
        else if (Environment.isLinuxPlatform()) {
            if (!config.cachePath ||
                !config.serviceName ||
                !config.accountName) {
                throw PersistenceError.createPersistenceNotValidatedError("Cache path, service name and/or account name not provided for the LibSecretPersistence cache plugin");
            }
            peristence = await LibSecretPersistence.create(config.cachePath, config.serviceName, config.accountName, config.loggerOptions);
        }
        else {
            throw PersistenceError.createNotSupportedError("The current environment is not supported by msal-node-extensions yet.");
        }
        await peristence.verifyPersistence().catch(async (e) => {
            if (Environment.isLinuxPlatform() &&
                config.usePlaintextFileOnLinux) {
                if (!config.cachePath) {
                    throw PersistenceError.createPersistenceNotValidatedError("Cache path not provided for the FilePersistence cache plugin");
                }
                peristence = await FilePersistence.create(config.cachePath, config.loggerOptions);
                const isFilePersistenceVerified = await peristence.verifyPersistence();
                if (isFilePersistenceVerified) {
                    return peristence;
                }
                throw PersistenceError.createPersistenceNotVerifiedError("Persistence could not be verified");
            }
            else {
                throw e;
            }
        });
        return peristence;
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
class NativeAuthError extends AuthError {
    constructor(errorStatus, errorContext, errorCode, errorTag) {
        super(errorStatus, errorContext);
        this.name = "NativeAuthError";
        this.statusCode = errorCode;
        this.tag = errorTag;
        Object.setPrototypeOf(this, NativeAuthError.prototype);
    }
}

/* eslint-disable header/header */
const name = "@azure/msal-node-extensions";
const version = "1.5.17";

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
class NativeBrokerPlugin {
    constructor() {
        const defaultLoggerOptions = {
            loggerCallback: () => {
                // Empty logger callback
            },
            piiLoggingEnabled: false,
        };
        this.logger = new Logger(defaultLoggerOptions, name, version); // Default logger
        this.isBrokerAvailable = msalNodeRuntime.msalNodeRuntime.StartupError ? false : true;
    }
    setLogger(loggerOptions) {
        this.logger = new Logger(loggerOptions, name, version);
        const logCallback = (message, logLevel, containsPii) => {
            switch (logLevel) {
                case msalNodeRuntime.LogLevel.Trace:
                    if (containsPii) {
                        this.logger.tracePii(message);
                    }
                    else {
                        this.logger.trace(message);
                    }
                    break;
                case msalNodeRuntime.LogLevel.Debug:
                    if (containsPii) {
                        this.logger.tracePii(message);
                    }
                    else {
                        this.logger.trace(message);
                    }
                    break;
                case msalNodeRuntime.LogLevel.Info:
                    if (containsPii) {
                        this.logger.infoPii(message);
                    }
                    else {
                        this.logger.info(message);
                    }
                    break;
                case msalNodeRuntime.LogLevel.Warning:
                    if (containsPii) {
                        this.logger.warningPii(message);
                    }
                    else {
                        this.logger.warning(message);
                    }
                    break;
                case msalNodeRuntime.LogLevel.Error:
                    if (containsPii) {
                        this.logger.errorPii(message);
                    }
                    else {
                        this.logger.error(message);
                    }
                    break;
                case msalNodeRuntime.LogLevel.Fatal:
                    if (containsPii) {
                        this.logger.errorPii(message);
                    }
                    else {
                        this.logger.error(message);
                    }
                    break;
                default:
                    if (containsPii) {
                        this.logger.infoPii(message);
                    }
                    else {
                        this.logger.info(message);
                    }
                    break;
            }
        };
        try {
            msalNodeRuntime.msalNodeRuntime.RegisterLogger(logCallback, loggerOptions.piiLoggingEnabled || false);
        }
        catch (e) {
            const wrappedError = this.wrapError(e);
            if (wrappedError) {
                throw wrappedError;
            }
        }
    }
    async getAccountById(accountId, correlationId) {
        this.logger.trace("NativeBrokerPlugin - getAccountById called", correlationId);
        const readAccountResult = await this.readAccountById(accountId, correlationId);
        return this.generateAccountInfo(readAccountResult.account);
    }
    async getAllAccounts(clientId, correlationId) {
        this.logger.trace("NativeBrokerPlugin - getAllAccounts called", correlationId);
        return new Promise((resolve, reject) => {
            const resultCallback = (result) => {
                try {
                    result.CheckError();
                }
                catch (e) {
                    const wrappedError = this.wrapError(e);
                    if (wrappedError) {
                        reject(wrappedError);
                        return;
                    }
                }
                const accountInfoResult = [];
                result.accounts.forEach((account) => {
                    accountInfoResult.push(this.generateAccountInfo(account));
                });
                resolve(accountInfoResult);
            };
            try {
                msalNodeRuntime.msalNodeRuntime.DiscoverAccountsAsync(clientId, correlationId, resultCallback);
            }
            catch (e) {
                const wrappedError = this.wrapError(e);
                if (wrappedError) {
                    reject(wrappedError);
                }
            }
        });
    }
    async acquireTokenSilent(request) {
        this.logger.trace("NativeBrokerPlugin - acquireTokenSilent called", request.correlationId);
        const authParams = this.generateRequestParameters(request);
        const account = await this.getAccount(request);
        return new Promise((resolve, reject) => {
            const resultCallback = (result) => {
                try {
                    result.CheckError();
                }
                catch (e) {
                    const wrappedError = this.wrapError(e);
                    if (wrappedError) {
                        reject(wrappedError);
                        return;
                    }
                }
                const authenticationResult = this.getAuthenticationResult(request, result);
                resolve(authenticationResult);
            };
            try {
                if (account) {
                    msalNodeRuntime.msalNodeRuntime.AcquireTokenSilentlyAsync(authParams, request.correlationId, account, resultCallback);
                }
                else {
                    msalNodeRuntime.msalNodeRuntime.SignInSilentlyAsync(authParams, request.correlationId, resultCallback);
                }
            }
            catch (e) {
                const wrappedError = this.wrapError(e);
                if (wrappedError) {
                    reject(wrappedError);
                }
            }
        });
    }
    async acquireTokenInteractive(request, providedWindowHandle) {
        this.logger.trace("NativeBrokerPlugin - acquireTokenInteractive called", request.correlationId);
        const authParams = this.generateRequestParameters(request);
        const account = await this.getAccount(request);
        const windowHandle = providedWindowHandle || Buffer.from([0]);
        return new Promise((resolve, reject) => {
            const resultCallback = (result) => {
                try {
                    result.CheckError();
                }
                catch (e) {
                    const wrappedError = this.wrapError(e);
                    if (wrappedError) {
                        reject(wrappedError);
                        return;
                    }
                }
                const authenticationResult = this.getAuthenticationResult(request, result);
                resolve(authenticationResult);
            };
            try {
                switch (request.prompt) {
                    case PromptValue.LOGIN:
                    case PromptValue.SELECT_ACCOUNT:
                    case PromptValue.CREATE:
                        this.logger.info("Calling native interop SignInInteractively API", request.correlationId);
                        const loginHint = request.loginHint || Constants.EMPTY_STRING;
                        msalNodeRuntime.msalNodeRuntime.SignInInteractivelyAsync(windowHandle, authParams, request.correlationId, loginHint, resultCallback);
                        break;
                    case PromptValue.NONE:
                        if (account) {
                            this.logger.info("Calling native interop AcquireTokenSilently API", request.correlationId);
                            msalNodeRuntime.msalNodeRuntime.AcquireTokenSilentlyAsync(authParams, request.correlationId, account, resultCallback);
                        }
                        else {
                            this.logger.info("Calling native interop SignInSilently API", request.correlationId);
                            msalNodeRuntime.msalNodeRuntime.SignInSilentlyAsync(authParams, request.correlationId, resultCallback);
                        }
                        break;
                    default:
                        if (account) {
                            this.logger.info("Calling native interop AcquireTokenInteractively API", request.correlationId);
                            msalNodeRuntime.msalNodeRuntime.AcquireTokenInteractivelyAsync(windowHandle, authParams, request.correlationId, account, resultCallback);
                        }
                        else {
                            this.logger.info("Calling native interop SignIn API", request.correlationId);
                            const loginHint = request.loginHint || Constants.EMPTY_STRING;
                            msalNodeRuntime.msalNodeRuntime.SignInAsync(windowHandle, authParams, request.correlationId, loginHint, resultCallback);
                        }
                        break;
                }
            }
            catch (e) {
                const wrappedError = this.wrapError(e);
                if (wrappedError) {
                    reject(wrappedError);
                }
            }
        });
    }
    async signOut(request) {
        this.logger.trace("NativeBrokerPlugin - signOut called", request.correlationId);
        const account = await this.getAccount(request);
        if (!account) {
            throw createClientAuthError(noAccountFound);
        }
        return new Promise((resolve, reject) => {
            const resultCallback = (result) => {
                try {
                    result.CheckError();
                }
                catch (e) {
                    const wrappedError = this.wrapError(e);
                    if (wrappedError) {
                        reject(wrappedError);
                        return;
                    }
                }
                resolve();
            };
            try {
                msalNodeRuntime.msalNodeRuntime.SignOutSilentlyAsync(request.clientId, request.correlationId, account, resultCallback);
            }
            catch (e) {
                const wrappedError = this.wrapError(e);
                if (wrappedError) {
                    reject(wrappedError);
                }
            }
        });
    }
    async getAccount(request) {
        if (request.accountId) {
            const readAccountResult = await this.readAccountById(request.accountId, request.correlationId);
            return readAccountResult.account;
        }
        return null;
    }
    async readAccountById(accountId, correlationId) {
        this.logger.trace("NativeBrokerPlugin - readAccountById called", correlationId);
        return new Promise((resolve, reject) => {
            const resultCallback = (result) => {
                try {
                    result.CheckError();
                }
                catch (e) {
                    const wrappedError = this.wrapError(e);
                    if (wrappedError) {
                        reject(wrappedError);
                        return;
                    }
                }
                resolve(result);
            };
            try {
                msalNodeRuntime.msalNodeRuntime.ReadAccountByIdAsync(accountId, correlationId, resultCallback);
            }
            catch (e) {
                const wrappedError = this.wrapError(e);
                if (wrappedError) {
                    reject(wrappedError);
                }
            }
        });
    }
    generateRequestParameters(request) {
        this.logger.trace("NativeBrokerPlugin - generateRequestParameters called", request.correlationId);
        const authParams = new msalNodeRuntime.msalNodeRuntime.AuthParameters();
        try {
            authParams.CreateAuthParameters(request.clientId, request.authority);
            authParams.SetRedirectUri(request.redirectUri);
            authParams.SetRequestedScopes(request.scopes.join(" "));
            if (request.claims) {
                authParams.SetDecodedClaims(request.claims);
            }
            if (request.authenticationScheme === AuthenticationScheme.POP) {
                if (!request.resourceRequestMethod ||
                    !request.resourceRequestUri) {
                    throw new Error("Authentication Scheme set to POP but one or more of the following parameters are missing: resourceRequestMethod, resourceRequestUri");
                }
                const resourceUrl = new URL(request.resourceRequestUri);
                authParams.SetPopParams(request.resourceRequestMethod, resourceUrl.host, resourceUrl.pathname, request.shrNonce || "");
            }
            if (request.extraParameters) {
                Object.entries(request.extraParameters).forEach(([key, value]) => {
                    authParams.SetAdditionalParameter(key, value);
                });
            }
            const skus = request.extraParameters &&
                request.extraParameters[X_CLIENT_EXTRA_SKU]
                    ?.length
                ? request.extraParameters[X_CLIENT_EXTRA_SKU]
                : "";
            authParams.SetAdditionalParameter(X_CLIENT_EXTRA_SKU, ServerTelemetryManager.makeExtraSkuString({
                skus,
                extensionName: "msal.node.ext",
                extensionVersion: version,
            }));
        }
        catch (e) {
            const wrappedError = this.wrapError(e);
            if (wrappedError) {
                throw wrappedError;
            }
        }
        return authParams;
    }
    getAuthenticationResult(request, authResult) {
        this.logger.trace("NativeBrokerPlugin - getAuthenticationResult called", request.correlationId);
        let fromCache = false;
        try {
            const telemetryJSON = JSON.parse(authResult.telemetryData);
            fromCache = !!telemetryJSON["is_cache"];
        }
        catch (e) {
            this.logger.error("NativeBrokerPlugin: getAuthenticationResult - Error parsing telemetry data. Could not determine if response came from cache.", request.correlationId);
        }
        let idTokenClaims;
        try {
            idTokenClaims = JSON.parse(authResult.idToken);
        }
        catch (e) {
            throw new Error("Unable to parse idToken claims");
        }
        const accountInfo = this.generateAccountInfo(authResult.account, idTokenClaims);
        let accessToken;
        let tokenType;
        if (authResult.isPopAuthorization) {
            // Header includes 'pop ' prefix
            accessToken = authResult.authorizationHeader.split(" ")[1];
            tokenType = AuthenticationScheme.POP;
        }
        else {
            accessToken = authResult.accessToken;
            tokenType = AuthenticationScheme.BEARER;
        }
        const result = {
            authority: request.authority,
            uniqueId: idTokenClaims.oid || idTokenClaims.sub || "",
            tenantId: idTokenClaims.tid || "",
            scopes: authResult.grantedScopes.split(" "),
            account: accountInfo,
            idToken: authResult.rawIdToken,
            idTokenClaims: idTokenClaims,
            accessToken: accessToken,
            fromCache: fromCache,
            // MsalRuntime expiresOn returned in seconds, converting to Date for AuthenticationResult
            expiresOn: toDateFromSeconds(authResult.expiresOn),
            tokenType: tokenType,
            correlationId: request.correlationId,
            fromNativeBroker: true,
        };
        return result;
    }
    generateAccountInfo(account, idTokenClaims) {
        this.logger.trace("NativeBrokerPlugin - generateAccountInfo called");
        const accountInfo = {
            homeAccountId: account.homeAccountId,
            environment: account.environment,
            tenantId: account.realm,
            username: account.username,
            localAccountId: account.localAccountId,
            name: account.displayName,
            idTokenClaims: idTokenClaims,
            nativeAccountId: account.accountId,
        };
        return accountInfo;
    }
    isMsalRuntimeError(result) {
        return (result.hasOwnProperty("errorCode") ||
            result.hasOwnProperty("errorStatus") ||
            result.hasOwnProperty("errorContext") ||
            result.hasOwnProperty("errorTag"));
    }
    wrapError(error) {
        if (error &&
            typeof error === "object" &&
            this.isMsalRuntimeError(error)) {
            const { errorCode, errorStatus, errorContext, errorTag } = error;
            switch (errorStatus) {
                case msalNodeRuntime.ErrorStatus.InteractionRequired:
                case msalNodeRuntime.ErrorStatus.AccountUnusable:
                    return new InteractionRequiredAuthError(ErrorCodes.INTERATION_REQUIRED_ERROR_CODE, errorContext);
                case msalNodeRuntime.ErrorStatus.NoNetwork:
                case msalNodeRuntime.ErrorStatus.NetworkTemporarilyUnavailable:
                    return createClientAuthError(noNetworkConnectivity);
                case msalNodeRuntime.ErrorStatus.ServerTemporarilyUnavailable:
                    return new ServerError(ErrorCodes.SERVER_UNAVAILABLE, errorContext);
                case msalNodeRuntime.ErrorStatus.UserCanceled:
                    return createClientAuthError(userCanceled);
                case msalNodeRuntime.ErrorStatus.AuthorityUntrusted:
                    return createClientConfigurationError(untrustedAuthority);
                case msalNodeRuntime.ErrorStatus.UserSwitched:
                    // Not an error case, if there's customer demand we can surface this as a response property
                    return null;
                case msalNodeRuntime.ErrorStatus.AccountNotFound:
                    return createClientAuthError(noAccountFound);
                default:
                    return new NativeAuthError(msalNodeRuntime.ErrorStatus[errorStatus], errorContext, errorCode, errorTag);
            }
        }
        throw error;
    }
}

exports.DataProtectionScope = DataProtectionScope;
exports.Environment = Environment;
exports.FilePersistence = FilePersistence;
exports.FilePersistenceWithDataProtection = FilePersistenceWithDataProtection;
exports.KeychainPersistence = KeychainPersistence;
exports.LibSecretPersistence = LibSecretPersistence;
exports.NativeBrokerPlugin = NativeBrokerPlugin;
exports.PersistenceCachePlugin = PersistenceCachePlugin;
exports.PersistenceCreator = PersistenceCreator;
//# sourceMappingURL=msal-node-extensions.cjs.map
