@azure/msal-browser
Version:
Microsoft Authentication Library for js
98 lines (95 loc) • 4.03 kB
JavaScript
/*! @azure/msal-browser v5.6.3 2026-04-01 */
;
import { ProtocolUtils, UrlString } from '@azure/msal-common/browser';
export { invoke, invokeAsync } from '@azure/msal-common/browser';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { emptyResponse, noStateInHash, unableToParseState } from '../error/BrowserAuthErrorCodes.mjs';
import { base64Decode } from '../encode/Base64Decode.mjs';
/*
* 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);
}
if (!payload || !params) {
throw createBrowserAuthError(emptyResponse);
}
const state = params.get("state");
if (!state) {
throw createBrowserAuthError(noStateInHash);
}
const { libraryState } = ProtocolUtils.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,
},
};
}
/**
* Gets the homepage url for the current window location.
*/
function getHomepage() {
const currentUrl = new UrlString(window.location.href);
const urlComponents = currentUrl.getUrlComponents();
return `${urlComponents.Protocol}//${urlComponents.HostNameAndPort}/`;
}
export { getHomepage, parseAuthResponseFromUrl };
//# sourceMappingURL=BrowserUtils.mjs.map