/*! @azure/msal-browser v5.15.0 2026-06-23 */
'use strict';
'use strict';

/*! @azure/msal-common v16.10.0 2026-06-23 */
// Resource delimiter - used for certain cache entries
const RESOURCE_DELIM = "|";
const FORWARD_SLASH = "/";
/**
 * String constants related to AAD Authority
 */
const AADAuthority = {
    COMMON: "common",
    ORGANIZATIONS: "organizations"};

/*! @azure/msal-common v16.10.0 2026-06-23 */
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
function getDefaultErrorMessage$1(code) {
    return `See https://aka.ms/msal.js.errors#${code} for details`;
}
/**
 * General error class thrown by the MSAL.js library.
 */
class AuthError extends Error {
    constructor(errorCode, correlationId, errorMessage, suberror) {
        const message = errorMessage ||
            (errorCode ? getDefaultErrorMessage$1(errorCode) : "");
        const errorString = message ? `${errorCode}: ${message}` : errorCode;
        super(errorString);
        Object.setPrototypeOf(this, AuthError.prototype);
        this.errorCode = errorCode || "";
        this.errorMessage = message || "";
        this.subError = suberror || "";
        this.correlationId = correlationId;
        this.name = "AuthError";
    }
}

/*! @azure/msal-common v16.10.0 2026-06-23 */

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Error thrown when there is an error in configuration of the MSAL.js library.
 */
class ClientConfigurationError extends AuthError {
    constructor(errorCode, correlationId) {
        super(errorCode, correlationId);
        this.name = "ClientConfigurationError";
        Object.setPrototypeOf(this, ClientConfigurationError.prototype);
    }
}
function createClientConfigurationError(errorCode, correlationId) {
    return new ClientConfigurationError(errorCode, correlationId);
}

/*! @azure/msal-common v16.10.0 2026-06-23 */
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * @hidden
 */
class StringUtils {
    /**
     * Check if stringified object is empty
     * @param strObj
     */
    static isEmptyObj(strObj) {
        if (strObj) {
            try {
                const obj = JSON.parse(strObj);
                return Object.keys(obj).length === 0;
            }
            catch (e) { }
        }
        return true;
    }
    static startsWith(str, search) {
        return str.indexOf(search) === 0;
    }
    static endsWith(str, search) {
        return (str.length >= search.length &&
            str.lastIndexOf(search) === str.length - search.length);
    }
    /**
     * Parses string into an object.
     *
     * @param query
     */
    static queryStringToObject(query) {
        const obj = {};
        const params = query.split("&");
        const decode = (s) => decodeURIComponent(s.replace(/\+/g, " "));
        params.forEach((pair) => {
            if (pair.trim()) {
                const [key, value] = pair.split(/=(.+)/g, 2); // Split on the first occurence of the '=' character
                if (key && value) {
                    obj[decode(key)] = decode(value);
                }
            }
        });
        return obj;
    }
    /**
     * Trims entries in an array.
     *
     * @param arr
     */
    static trimArrayEntries(arr) {
        return arr.map((entry) => entry.trim());
    }
    /**
     * Removes empty strings from array
     * @param arr
     */
    static removeEmptyStringsFromArray(arr) {
        return arr.filter((entry) => {
            return !!entry;
        });
    }
    /**
     * Attempts to parse a string into JSON
     * @param str
     */
    static jsonParseHelper(str) {
        try {
            return JSON.parse(str);
        }
        catch (e) {
            return null;
        }
    }
}

/*! @azure/msal-common v16.10.0 2026-06-23 */

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * ClientAuthErrorMessage class containing string constants used by error codes and messages.
 */
/**
 * Error thrown when there is an error in the client code running on the browser.
 */
class ClientAuthError extends AuthError {
    constructor(errorCode, correlationId, additionalMessage) {
        super(errorCode, correlationId, additionalMessage);
        this.name = "ClientAuthError";
        Object.setPrototypeOf(this, ClientAuthError.prototype);
    }
}
function createClientAuthError(errorCode, correlationId, additionalMessage) {
    return new ClientAuthError(errorCode, correlationId, additionalMessage);
}

/*! @azure/msal-common v16.10.0 2026-06-23 */
const authorityUriInsecure = "authority_uri_insecure";
const urlParseError = "url_parse_error";
const urlEmptyError = "empty_url_error";

/*! @azure/msal-common v16.10.0 2026-06-23 */
const invalidState = "invalid_state";
const noCryptoObject = "no_crypto_object";

/*! @azure/msal-common v16.10.0 2026-06-23 */

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Url object class which can perform various transformations on url strings.
 */
class UrlString {
    get urlString() {
        return this._urlString;
    }
    constructor(url, correlationId) {
        this._urlString = url;
        this.correlationId = correlationId;
        if (!this._urlString) {
            // Throws error if url is empty
            throw createClientConfigurationError(urlEmptyError, correlationId);
        }
        if (!url.includes("#")) {
            this._urlString = UrlString.canonicalizeUri(url);
        }
    }
    /**
     * Ensure urls are lower case and end with a / character.
     * @param url
     */
    static canonicalizeUri(url) {
        if (url) {
            let lowerCaseUrl = url.toLowerCase();
            if (StringUtils.endsWith(lowerCaseUrl, "?")) {
                lowerCaseUrl = lowerCaseUrl.slice(0, -1);
            }
            else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
                lowerCaseUrl = lowerCaseUrl.slice(0, -2);
            }
            if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
                lowerCaseUrl += "/";
            }
            return lowerCaseUrl;
        }
        return url;
    }
    /**
     * Throws if urlString passed is not a valid authority URI string.
     */
    validateAsUri() {
        // Attempts to parse url for uri components
        let components;
        try {
            components = this.getUrlComponents();
        }
        catch (e) {
            throw createClientConfigurationError(urlParseError, this.correlationId);
        }
        // Throw error if URI or path segments are not parseable.
        if (!components.HostNameAndPort || !components.PathSegments) {
            throw createClientConfigurationError(urlParseError, this.correlationId);
        }
        // Throw error if uri is insecure.
        if (!components.Protocol ||
            components.Protocol.toLowerCase() !== "https:") {
            throw createClientConfigurationError(authorityUriInsecure, this.correlationId);
        }
    }
    /**
     * Given a url and a query string return the url with provided query string appended
     * @param url
     * @param queryString
     */
    static appendQueryString(url, queryString) {
        if (!queryString) {
            return url;
        }
        return url.indexOf("?") < 0
            ? `${url}?${queryString}`
            : `${url}&${queryString}`;
    }
    /**
     * Returns a url with the hash removed
     * @param url
     */
    static removeHashFromUrl(url) {
        return UrlString.canonicalizeUri(url.split("#")[0]);
    }
    /**
     * Given a url like https://a:b/common/d?e=f#g, and a tenantId, returns https://a:b/tenantId/d
     * @param href The url
     * @param tenantId The tenant id to replace
     */
    replaceTenantPath(tenantId) {
        const urlObject = this.getUrlComponents();
        const pathArray = urlObject.PathSegments;
        if (tenantId &&
            pathArray.length !== 0 &&
            (pathArray[0] === AADAuthority.COMMON ||
                pathArray[0] === AADAuthority.ORGANIZATIONS)) {
            pathArray[0] = tenantId;
        }
        return UrlString.constructAuthorityUriFromObject(urlObject, this.correlationId);
    }
    /**
     * Parses out the components from a url string.
     * @returns An object with the various components. Please cache this value insted of calling this multiple times on the same url.
     */
    getUrlComponents() {
        // https://gist.github.com/curtisz/11139b2cfcaef4a261e0
        const regEx = RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
        // If url string does not match regEx, we throw an error
        const match = this.urlString.match(regEx);
        if (!match) {
            throw createClientConfigurationError(urlParseError, this.correlationId);
        }
        // Url component object
        const urlComponents = {
            Protocol: match[1],
            HostNameAndPort: match[4],
            AbsolutePath: match[5],
            QueryString: match[7],
        };
        let pathSegments = urlComponents.AbsolutePath.split("/");
        pathSegments = pathSegments.filter((val) => val && val.length > 0); // remove empty elements
        urlComponents.PathSegments = pathSegments;
        if (urlComponents.QueryString &&
            urlComponents.QueryString.endsWith("/")) {
            urlComponents.QueryString = urlComponents.QueryString.substring(0, urlComponents.QueryString.length - 1);
        }
        return urlComponents;
    }
    static getDomainFromUrl(url, correlationId) {
        const regEx = RegExp("^([^:/?#]+://)?([^/?#]*)");
        const match = url.match(regEx);
        if (!match) {
            throw createClientConfigurationError(urlParseError, correlationId);
        }
        return match[2];
    }
    static getAbsoluteUrl(relativeUrl, baseUrl, correlationId) {
        if (relativeUrl[0] === FORWARD_SLASH) {
            const url = new UrlString(baseUrl, correlationId);
            const baseComponents = url.getUrlComponents();
            return (baseComponents.Protocol +
                "//" +
                baseComponents.HostNameAndPort +
                relativeUrl);
        }
        return relativeUrl;
    }
    static constructAuthorityUriFromObject(urlObject, correlationId) {
        return new UrlString(urlObject.Protocol +
            "//" +
            urlObject.HostNameAndPort +
            "/" +
            urlObject.PathSegments.join("/"), correlationId);
    }
}

/*! @azure/msal-common v16.10.0 2026-06-23 */
/**
 * Parses the state into the RequestStateObject, which contains the LibraryState info and the state passed by the user.
 * @param base64Decode
 * @param state
 * @param correlationId
 */
function parseRequestState(base64Decode, state, correlationId) {
    if (!base64Decode) {
        throw createClientAuthError(noCryptoObject, correlationId);
    }
    if (!state) {
        throw createClientAuthError(invalidState, correlationId);
    }
    try {
        // Split the state between library state and user passed state and decode them separately
        const splitState = state.split(RESOURCE_DELIM);
        const libraryState = splitState[0];
        const userState = splitState.length > 1
            ? splitState.slice(1).join(RESOURCE_DELIM)
            : "";
        const libraryStateString = base64Decode(libraryState);
        const libraryStateObj = JSON.parse(libraryStateString);
        return {
            userRequestState: userState || "",
            libraryState: libraryStateObj,
        };
    }
    catch (e) {
        throw createClientAuthError(invalidState, correlationId);
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const noStateInHash = "no_state_in_hash";
const unableToParseState = "unable_to_parse_state";
const invalidBase64String = "invalid_base64_string";
const timedOut = "timed_out";
const emptyResponse = "empty_response";

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
function getDefaultErrorMessage(code) {
    return `See https://aka.ms/msal.js.errors#${code} for details`;
}
/**
 * Browser library error class thrown by the MSAL.js library for SPAs
 */
class BrowserAuthError extends AuthError {
    constructor(errorCode, correlationId, subError) {
        super(errorCode, correlationId, getDefaultErrorMessage(errorCode), subError);
        Object.setPrototypeOf(this, BrowserAuthError.prototype);
        this.name = "BrowserAuthError";
    }
}
function createBrowserAuthError(errorCode, correlationId, subError) {
    return new BrowserAuthError(errorCode, correlationId, subError);
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Class which exposes APIs to decode base64 strings to plaintext. See here for implementation details:
 * https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
 */
/**
 * Returns a URL-safe plaintext decoded string from b64 encoded input.
 * @param input
 */
function base64Decode(input) {
    return new TextDecoder().decode(base64DecToArr(input));
}
/**
 * Decodes base64 into Uint8Array
 * @param base64String
 */
function base64DecToArr(base64String) {
    let encodedString = base64String.replace(/-/g, "+").replace(/_/g, "/");
    switch (encodedString.length % 4) {
        case 0:
            break;
        case 2:
            encodedString += "==";
            break;
        case 3:
            encodedString += "=";
            break;
        default:
            throw createBrowserAuthError(invalidBase64String, "");
    }
    const binString = atob(encodedString);
    return Uint8Array.from(binString, (m) => m.codePointAt(0) || 0);
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const INTERACTION_TYPE = {
    SIGNOUT: "signout",
};
/**
 * Temporary cache keys for MSAL, deleted after any request.
 */
const TemporaryCacheKeys = {
    ORIGIN_URI: "request.origin",
    URL_HASH: "urlHash",
    REQUEST_PARAMS: "request.params",
    VERIFIER: "code.verifier",
    INTERACTION_STATUS_KEY: "interaction.status",
    NATIVE_REQUEST: "request.native",
};
/**
 * 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
 * 800-899 Auth Code Flow
 * 900-999 Misc
 */
const ApiId = {
    handleRedirectPromise: 865,
    logout: 961};
/*
 * Interaction type of the API - used for state and telemetry
 */
var InteractionType;
(function (InteractionType) {
    InteractionType["Redirect"] = "redirect";
    InteractionType["Popup"] = "popup";
    InteractionType["Silent"] = "silent";
    InteractionType["None"] = "none";
})(InteractionType || (InteractionType = {}));

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Extracts and parses the authentication response from URL (hash and/or query string).
 * This is a shared utility used across multiple components in msal-browser.
 *
 * @returns {Object} An object containing the parsed state information and URL parameters.
 * @returns {URLSearchParams} params - The parsed URL parameters from the payload.
 * @returns {string} payload - The combined query string and hash content.
 * @returns {string} urlHash - The original URL hash.
 * @returns {string} urlQuery - The original URL query string.
 * @returns {LibraryStateObject} libraryState - The decoded library state from the state parameter.
 *
 * @throws {AuthError} If no authentication payload is found in the URL.
 * @throws {AuthError} If the state parameter is missing.
 * @throws {AuthError} If the state is missing required 'id' or 'meta' attributes.
 */
function parseAuthResponseFromUrl() {
    // Extract both hash and query string to support hybrid response format
    const urlHash = window.location.hash;
    const urlQuery = window.location.search;
    // Determine which part contains the auth response by checking for 'state' parameter
    let hasResponseInHash = false;
    let hasResponseInQuery = false;
    let payload = "";
    let params = undefined;
    if (urlHash && urlHash.length > 1) {
        const hashContent = urlHash.charAt(0) === "#" ? urlHash.substring(1) : urlHash;
        const hashParams = new URLSearchParams(hashContent);
        if (hashParams.has("state")) {
            hasResponseInHash = true;
            payload = hashContent;
            params = hashParams;
        }
    }
    if (urlQuery && urlQuery.length > 1) {
        const queryContent = urlQuery.charAt(0) === "?" ? urlQuery.substring(1) : urlQuery;
        const queryParams = new URLSearchParams(queryContent);
        if (queryParams.has("state")) {
            hasResponseInQuery = true;
            payload = queryContent;
            params = queryParams;
        }
    }
    // If response is in both, combine them (hybrid format)
    if (hasResponseInHash && hasResponseInQuery) {
        const queryContent = urlQuery.charAt(0) === "?" ? urlQuery.substring(1) : urlQuery;
        const hashContent = urlHash.charAt(0) === "#" ? urlHash.substring(1) : urlHash;
        payload = `${queryContent}${hashContent}`;
        params = new URLSearchParams(payload);
    }
    /*
     * Called by the redirect-bridge entry point before any request context exists,
     * so correlationId is intentionally empty for the throws below.
     */
    if (!payload || !params) {
        throw createBrowserAuthError(emptyResponse, "");
    }
    const state = params.get("state");
    if (!state) {
        throw createBrowserAuthError(noStateInHash, "");
    }
    const { libraryState } = parseRequestState(base64Decode, state, "");
    const { id, meta } = libraryState;
    if (!id || !meta) {
        throw createBrowserAuthError(unableToParseState, "", "missing_library_state");
    }
    return {
        params,
        payload,
        urlHash,
        urlQuery,
        hasResponseInHash,
        hasResponseInQuery,
        libraryState: {
            id,
            meta,
        },
    };
}
/**
 * Strips both hash and query string from the given window's URL by replacing
 * with origin + pathname only. Used to remove auth response parameters
 * (auth code, state, etc.) before the window is closed or navigated away.
 */
function clearAuthResponseFromUrl(contentWindow) {
    if (typeof contentWindow.history?.replaceState === "function") {
        contentWindow.history.replaceState(null, "", `${contentWindow.location.origin}${contentWindow.location.pathname}`);
    }
}
/**
 * Gets the homepage url for the current window location.
 */
function getHomepage(correlationId) {
    const currentUrl = new UrlString(window.location.href, "");
    const urlComponents = currentUrl.getUrlComponents();
    return `${urlComponents.Protocol}//${urlComponents.HostNameAndPort}/`;
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
class NavigationClient {
    /**
     * Navigates to other pages within the same web application
     * @param url
     * @param options
     */
    navigateInternal(url, options) {
        return NavigationClient.defaultNavigateWindow(url, options);
    }
    /**
     * Navigates to other pages outside the web application i.e. the Identity Provider
     * @param url
     * @param options
     */
    navigateExternal(url, options) {
        return NavigationClient.defaultNavigateWindow(url, options);
    }
    /**
     * Default navigation implementation invoked by the internal and external functions
     * @param url
     * @param options
     */
    static defaultNavigateWindow(url, options) {
        if (options.noHistory) {
            window.location.replace(url); // CodeQL [SM03712] Application owner controls the URL. User can't change it.
        }
        else {
            window.location.assign(url); // CodeQL [SM03712] Application owner controls the URL. User can't change it.
        }
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                reject(createBrowserAuthError(timedOut, "", "failed_to_redirect"));
            }, options.timeout);
        });
    }
}

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const DEFAULT_REDIRECT_TIMEOUT_MS = 30000;

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const PREFIX = "msal";

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * Processes the authentication response from the redirect URL
 * For SSO and popup scenarios broadcasts it to the main frame
 * For redirect scenario navigates to the home page
 *
 * @param {NavigationClient} navigationClient - Optional navigation client for redirect scenario.
 *
 * @returns {Promise<void>} A promise that resolves when the response has been broadcast and cleanup is complete.
 *
 * @throws {AuthError} If no authentication payload is found in the URL (hash or query string).
 * @throws {AuthError} If the state parameter is missing from the redirect URL.
 * @throws {AuthError} If the state is missing required 'id' or 'meta' attributes.
 */
async function broadcastResponseToMainFrame(navigationClient) {
    document.title = "Microsoft Authentication";
    let parsedResponse;
    try {
        parsedResponse = parseAuthResponseFromUrl();
    }
    catch (error) {
        // Clear hash and query string before re-throwing parse errors
        clearAuthResponseFromUrl(window);
        throw error;
    }
    const { payload, urlHash, urlQuery, hasResponseInHash, hasResponseInQuery, libraryState, } = parsedResponse;
    const { id, meta } = libraryState;
    if (meta["interactionType"] === InteractionType.Redirect) {
        const navClient = navigationClient || new NavigationClient();
        let navigateToUrl = "";
        let clientId = "";
        let interactionType = "";
        const interactionKey = `${PREFIX}.${TemporaryCacheKeys.INTERACTION_STATUS_KEY}`;
        /*
         * Retrieve the clientId and original navigation URL from
         * sessionStorage. If sessionStorage access or JSON.parse fails,
         * we fall back to URL-based navigation below.
         */
        try {
            const rawInteractionStatus = window.sessionStorage.getItem(interactionKey);
            const interactionStatus = JSON.parse(rawInteractionStatus || "");
            clientId = interactionStatus.clientId || "";
            interactionType = interactionStatus.type;
            if (clientId) {
                const originKey = `${PREFIX}.${clientId}.${TemporaryCacheKeys.ORIGIN_URI}`;
                navigateToUrl = window.sessionStorage.getItem(originKey) || "";
            }
        }
        catch {
            // sessionStorage access or JSON.parse failed
        }
        const navigationOptions = {
            apiId: interactionType === INTERACTION_TYPE.SIGNOUT
                ? ApiId.logout
                : ApiId.handleRedirectPromise,
            noHistory: true,
            timeout: DEFAULT_REDIRECT_TIMEOUT_MS,
        };
        /*
         * Cache the auth response payload in sessionStorage under the URL_HASH
         * key, then navigate directly to the origin URL. This replicates what
         * RedirectClient.handleRedirectPromise does when the current page is
         * not the loginRequestUrl: it caches the response and navigates.
         *
         * On the target page, handleRedirectPromise will find no response in
         * the URL but will pick up the cached payload from sessionStorage.
         * This avoids appending the auth response to the URL, which would
         * create malformed URLs for hash-routed SPAs (e.g. /#/route#code=...).
         *
         * If caching fails (clientId unavailable, quota exceeded, storage
         * disabled), we still navigate to the origin/homepage. The target
         * page's handleRedirectPromise will return null and the app can
         * handle re-authentication. Appending auth params to the URL would
         * not help because handleRedirectPromise also relies on
         * sessionStorage to persist tokens.
         */
        if (clientId) {
            try {
                window.sessionStorage.setItem(`${PREFIX}.${clientId}.${TemporaryCacheKeys.URL_HASH}`, payload);
            }
            catch {
                // sessionStorage write failed — navigate anyway; handleRedirectPromise will return null
            }
        }
        const url = navigateToUrl || getHomepage();
        // Strip bare trailing "?" (empty query string) to match canonical URL form
        const navigationUrl = url.endsWith("?") ? url.slice(0, -1) : url;
        await navClient.navigateInternal(navigationUrl, navigationOptions);
        // Do NOT clear URL for redirect flow - we're navigating away anyway
        return;
    }
    // Clear only the part(s) containing the auth response from redirect bridge URL
    if (typeof window.history.replaceState === "function") {
        let newUrl = `${window.location.origin}${window.location.pathname}`;
        // Preserve hash if it didn't contain the response
        if (!hasResponseInHash && urlHash) {
            newUrl += urlHash;
        }
        // Preserve query if it didn't contain the response
        if (!hasResponseInQuery && urlQuery) {
            newUrl += urlQuery;
        }
        window.history.replaceState(null, "", newUrl);
    }
    // Send the raw URL payload to the main frame
    const channel = new BroadcastChannel(id);
    channel.postMessage({
        v: 1,
        payload,
    });
    channel.close();
    try {
        window.close();
    }
    catch { }
}

exports.broadcastResponseToMainFrame = broadcastResponseToMainFrame;
//# sourceMappingURL=msal-redirect-bridge.cjs.map
