@azure/msal-browser
Advanced tools
Comparing version 3.4.0 to 3.5.0
@@ -1,2 +0,2 @@ | ||
import { ICrypto, IPerformanceClient, Logger, SignedHttpRequest, SignedHttpRequestParameters } from "@azure/msal-common"; | ||
import { ICrypto, IPerformanceClient, Logger, ShrOptions, SignedHttpRequest, SignedHttpRequestParameters } from "@azure/msal-common"; | ||
export type CachedKeyPair = { | ||
@@ -57,3 +57,3 @@ publicKey: CryptoKey; | ||
*/ | ||
signJwt(payload: SignedHttpRequest, kid: string, correlationId?: string): Promise<string>; | ||
signJwt(payload: SignedHttpRequest, kid: string, shrOptions?: ShrOptions, correlationId?: string): Promise<string>; | ||
/** | ||
@@ -60,0 +60,0 @@ * Returns the SHA-256 hash of an input string |
@@ -38,4 +38,4 @@ /** | ||
export { BrowserPerformanceMeasurement } from "./telemetry/BrowserPerformanceMeasurement"; | ||
export { AuthenticationScheme, AccountInfo, AccountEntity, IdTokenClaims, AuthError, AuthErrorCodes, AuthErrorMessage, ClientAuthError, ClientAuthErrorCodes, ClientAuthErrorMessage, ClientConfigurationError, ClientConfigurationErrorCodes, ClientConfigurationErrorMessage, InteractionRequiredAuthError, InteractionRequiredAuthErrorCodes, InteractionRequiredAuthErrorMessage, ServerError, INetworkModule, NetworkResponse, NetworkRequestOptions, ILoggerCallback, Logger, LogLevel, ProtocolMode, ServerResponseType, PromptValue, ExternalTokenResponse, StringUtils, UrlString, AzureCloudInstance, AzureCloudOptions, AuthenticationHeaderParser, OIDC_DEFAULT_SCOPES, PerformanceCallbackFunction, PerformanceEvent, PerformanceEvents, InProgressPerformanceEvent, } from "@azure/msal-common"; | ||
export { AuthenticationScheme, AccountInfo, AccountEntity, IdTokenClaims, AuthError, AuthErrorCodes, AuthErrorMessage, ClientAuthError, ClientAuthErrorCodes, ClientAuthErrorMessage, ClientConfigurationError, ClientConfigurationErrorCodes, ClientConfigurationErrorMessage, InteractionRequiredAuthError, InteractionRequiredAuthErrorCodes, InteractionRequiredAuthErrorMessage, ServerError, INetworkModule, NetworkResponse, NetworkRequestOptions, ILoggerCallback, Logger, LogLevel, ProtocolMode, ServerResponseType, PromptValue, ExternalTokenResponse, StringUtils, UrlString, JsonWebTokenTypes, AzureCloudInstance, AzureCloudOptions, AuthenticationHeaderParser, OIDC_DEFAULT_SCOPES, PerformanceCallbackFunction, PerformanceEvent, PerformanceEvents, InProgressPerformanceEvent, } from "@azure/msal-common"; | ||
export { version } from "./packageMetadata"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -52,3 +52,2 @@ import { ICrypto, INetworkModule, Logger, AccountInfo, BaseAuthRequest, ServerTelemetryManager, Authority, IPerformanceClient } from "@azure/msal-common"; | ||
* @param requestAuthority | ||
* @param requestCorrelationId | ||
*/ | ||
@@ -55,0 +54,0 @@ protected getDiscoveredAuthority(requestAuthority?: string): Promise<Authority>; |
@@ -63,8 +63,2 @@ import { CommonEndSessionRequest, IPerformanceClient, Logger, ICrypto } from "@azure/msal-common"; | ||
/** | ||
* Waits for user interaction in logout popup window | ||
* @param popupWindow | ||
* @returns | ||
*/ | ||
waitForLogoutPopup(popupWindow: Window): Promise<void>; | ||
/** | ||
* @hidden | ||
@@ -112,7 +106,3 @@ * | ||
generateLogoutPopupName(request: CommonEndSessionRequest): string; | ||
/** | ||
* Extracts the server response from the popup window | ||
*/ | ||
extractServerResponseStringFromPopup(popupWindow: Window, href: string): string; | ||
} | ||
//# sourceMappingURL=PopupClient.d.ts.map |
@@ -1,2 +0,2 @@ | ||
import { ServerTelemetryManager, ICrypto, Logger, IPerformanceClient } from "@azure/msal-common"; | ||
import { ServerTelemetryManager, ServerAuthorizationCodeResponse, ICrypto, Logger, IPerformanceClient } from "@azure/msal-common"; | ||
import { StandardInteractionClient } from "./StandardInteractionClient"; | ||
@@ -31,3 +31,3 @@ import { EndSessionRequest } from "../request/EndSessionRequest"; | ||
*/ | ||
protected getRedirectResponseHash(hash: string): string | null; | ||
protected getRedirectResponse(userProvidedResponse: string): [ServerAuthorizationCodeResponse | null, string]; | ||
/** | ||
@@ -38,3 +38,3 @@ * Checks if hash exists and handles in window. | ||
*/ | ||
protected handleHash(hash: string, state: string, serverTelemetryManager: ServerTelemetryManager): Promise<AuthenticationResult>; | ||
protected handleResponse(serverParams: ServerAuthorizationCodeResponse, serverTelemetryManager: ServerTelemetryManager): Promise<AuthenticationResult>; | ||
/** | ||
@@ -41,0 +41,0 @@ * Use to log out the current user, and redirect the user to the postLogoutRedirectUri. |
@@ -1,2 +0,2 @@ | ||
import { ServerTelemetryManager, CommonAuthorizationCodeRequest, AuthorizationCodeClient, ClientConfiguration, Authority, ServerAuthorizationCodeResponse, CommonEndSessionRequest, AccountInfo, AzureCloudOptions } from "@azure/msal-common"; | ||
import { ServerTelemetryManager, CommonAuthorizationCodeRequest, AuthorizationCodeClient, ClientConfiguration, Authority, CommonEndSessionRequest, AccountInfo, AzureCloudOptions } from "@azure/msal-common"; | ||
import { BaseInteractionClient } from "./BaseInteractionClient"; | ||
@@ -43,7 +43,2 @@ import { AuthorizationUrlRequest } from "../request/AuthorizationUrlRequest"; | ||
/** | ||
* @param hash | ||
* @param interactionType | ||
*/ | ||
protected validateAndExtractStateFromHash(serverParams: ServerAuthorizationCodeResponse, interactionType: InteractionType, requestCorrelationId?: string): string; | ||
/** | ||
* Used to get a discovered version of the default authority. | ||
@@ -50,0 +45,0 @@ * @param requestAuthority |
@@ -1,2 +0,2 @@ | ||
import { AuthorizationCodePayload, CommonAuthorizationCodeRequest, AuthorizationCodeClient, CcsCredential, Logger, IPerformanceClient } from "@azure/msal-common"; | ||
import { AuthorizationCodePayload, CommonAuthorizationCodeRequest, AuthorizationCodeClient, CcsCredential, Logger, IPerformanceClient, ServerAuthorizationCodeResponse } from "@azure/msal-common"; | ||
import { BrowserCacheManager } from "../cache/BrowserCacheManager"; | ||
@@ -19,3 +19,3 @@ import { AuthenticationResult } from "../response/AuthenticationResult"; | ||
*/ | ||
handleCodeResponseFromHash(locationHash: string, request: AuthorizationUrlRequest): Promise<AuthenticationResult>; | ||
handleCodeResponse(response: ServerAuthorizationCodeResponse, request: AuthorizationUrlRequest): Promise<AuthenticationResult>; | ||
/** | ||
@@ -22,0 +22,0 @@ * Process auth code response from AAD |
@@ -1,2 +0,2 @@ | ||
import { AuthorizationCodeClient, CommonAuthorizationCodeRequest, Logger, IPerformanceClient, CcsCredential } from "@azure/msal-common"; | ||
import { AuthorizationCodeClient, CommonAuthorizationCodeRequest, Logger, IPerformanceClient, CcsCredential, ServerAuthorizationCodeResponse } from "@azure/msal-common"; | ||
import { BrowserCacheManager } from "../cache/BrowserCacheManager"; | ||
@@ -27,3 +27,3 @@ import { INavigationClient } from "../navigation/INavigationClient"; | ||
*/ | ||
handleCodeResponseFromHash(locationHash: string, state: string): Promise<AuthenticationResult>; | ||
handleCodeResponse(response: ServerAuthorizationCodeResponse, state: string): Promise<AuthenticationResult>; | ||
/** | ||
@@ -30,0 +30,0 @@ * Looks up ccs creds in the cache |
@@ -1,2 +0,2 @@ | ||
import { Logger, IPerformanceClient } from "@azure/msal-common"; | ||
import { Logger, IPerformanceClient, ServerResponseType } from "@azure/msal-common"; | ||
/** | ||
@@ -13,3 +13,3 @@ * Creates a hidden iframe to given URL using user-requested scopes as an id. | ||
*/ | ||
export declare function monitorIframeForHash(iframe: HTMLIFrameElement, timeout: number, pollIntervalMilliseconds: number, performanceClient: IPerformanceClient, logger: Logger, correlationId: string): Promise<string>; | ||
export declare function monitorIframeForHash(iframe: HTMLIFrameElement, timeout: number, pollIntervalMilliseconds: number, performanceClient: IPerformanceClient, logger: Logger, correlationId: string, responseType: ServerResponseType): Promise<string>; | ||
//# sourceMappingURL=SilentHandler.d.ts.map |
export declare const name = "@azure/msal-browser"; | ||
export declare const version = "3.4.0"; | ||
export declare const version = "3.5.0"; | ||
//# sourceMappingURL=packageMetadata.d.ts.map |
import { InteractionType } from "./BrowserConstants"; | ||
import { ICrypto, ServerAuthorizationCodeResponse } from "@azure/msal-common"; | ||
import { ICrypto } from "@azure/msal-common"; | ||
export type BrowserStateObject = { | ||
interactionType: InteractionType; | ||
}; | ||
export declare class BrowserProtocolUtils { | ||
/** | ||
* Extracts the BrowserStateObject from the state string. | ||
* @param browserCrypto | ||
* @param state | ||
*/ | ||
static extractBrowserRequestState(browserCrypto: ICrypto, state: string): BrowserStateObject | null; | ||
/** | ||
* Parses properties of server response from url hash | ||
* @param locationHash Hash from url | ||
*/ | ||
static parseServerResponseFromHash(locationHash: string): ServerAuthorizationCodeResponse; | ||
} | ||
/** | ||
* Extracts the BrowserStateObject from the state string. | ||
* @param browserCrypto | ||
* @param state | ||
*/ | ||
export declare function extractBrowserRequestState(browserCrypto: ICrypto, state: string): BrowserStateObject | null; | ||
//# sourceMappingURL=BrowserProtocolUtils.d.ts.map |
@@ -13,3 +13,3 @@ { | ||
}, | ||
"version": "3.4.0", | ||
"version": "3.5.0", | ||
"description": "Microsoft Authentication Library for js", | ||
@@ -104,4 +104,4 @@ "keywords": [ | ||
"dependencies": { | ||
"@azure/msal-common": "14.3.0" | ||
"@azure/msal-common": "14.4.0" | ||
} | ||
} |
@@ -12,2 +12,3 @@ /* | ||
PerformanceEvents, | ||
ShrOptions, | ||
SignedHttpRequest, | ||
@@ -165,2 +166,3 @@ SignedHttpRequestParameters, | ||
kid: string, | ||
shrOptions?: ShrOptions, | ||
correlationId?: string | ||
@@ -185,11 +187,11 @@ ): Promise<string> { | ||
const publicKeyJwkString = getSortedObjectString(publicKeyJwk); | ||
// Base64URL encode public key thumbprint with keyId only: BASE64URL({ kid: "FULL_PUBLIC_KEY_HASH" }) | ||
const encodedKeyIdThumbprint = urlEncode(JSON.stringify({ kid: kid })); | ||
// Generate header | ||
const shrHeader = JoseHeader.getShrHeaderString({ | ||
...shrOptions?.header, | ||
alg: publicKeyJwk.alg, | ||
kid: encodedKeyIdThumbprint, | ||
alg: publicKeyJwk.alg, | ||
}); | ||
const encodedShrHeader = urlEncode(shrHeader); | ||
@@ -196,0 +198,0 @@ |
@@ -138,2 +138,3 @@ /* | ||
UrlString, | ||
JsonWebTokenTypes, | ||
// AzureCloudInstance enum | ||
@@ -140,0 +141,0 @@ AzureCloudInstance, |
@@ -144,3 +144,3 @@ /* | ||
PerformanceEvents.InitializeBaseRequest, | ||
request.correlationId | ||
this.correlationId | ||
); | ||
@@ -270,3 +270,2 @@ const authority = request.authority || this.config.auth.authority; | ||
* @param requestAuthority | ||
* @param requestCorrelationId | ||
*/ | ||
@@ -273,0 +272,0 @@ protected async getDiscoveredAuthority( |
@@ -14,5 +14,3 @@ /* | ||
OIDC_DEFAULT_SCOPES, | ||
Constants, | ||
ProtocolUtils, | ||
ServerAuthorizationCodeResponse, | ||
PerformanceEvents, | ||
@@ -25,2 +23,3 @@ IPerformanceClient, | ||
invokeAsync, | ||
invoke, | ||
} from "@azure/msal-common"; | ||
@@ -52,2 +51,3 @@ import { StandardInteractionClient } from "./StandardInteractionClient"; | ||
import { AuthenticationResult } from "../response/AuthenticationResult"; | ||
import * as ResponseHandler from "../response/ResponseHandler"; | ||
@@ -290,6 +290,15 @@ export type PopupParams = { | ||
// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds. | ||
const hash = await this.monitorPopupForHash(popupWindow); | ||
// Deserialize hash fragment response parameters. | ||
const serverParams: ServerAuthorizationCodeResponse = | ||
UrlString.getDeserializedHash(hash); | ||
const responseString = await this.monitorPopupForHash(popupWindow); | ||
const serverParams = invoke( | ||
ResponseHandler.deserializeResponse, | ||
PerformanceEvents.DeserializeResponse, | ||
this.logger, | ||
this.performanceClient, | ||
this.correlationId | ||
)( | ||
responseString, | ||
this.config.auth.OIDCOptions.serverResponseType, | ||
this.logger | ||
); | ||
// Remove throttle if it exists | ||
@@ -345,4 +354,4 @@ ThrottlingUtils.removeThrottle( | ||
// Handle response from hash string. | ||
const result = await interactionHandler.handleCodeResponseFromHash( | ||
hash, | ||
const result = await interactionHandler.handleCodeResponse( | ||
serverParams, | ||
validRequest | ||
@@ -472,3 +481,5 @@ ); | ||
await this.waitForLogoutPopup(popupWindow); | ||
await this.monitorPopupForHash(popupWindow).catch(() => { | ||
// Swallow any errors related to monitoring the window. Server logout is best effort | ||
}); | ||
@@ -554,12 +565,3 @@ if (mainWindowRedirectUri) { | ||
monitorPopupForHash(popupWindow: Window): Promise<string> { | ||
return new Promise((resolve, reject) => { | ||
/* | ||
* Polling for popups needs to be tick-based, | ||
* since a non-trivial amount of time can be spent on interaction (which should not count against the timeout). | ||
*/ | ||
const maxTicks = | ||
this.config.system.windowHashTimeout / | ||
this.config.system.pollIntervalMilliseconds; | ||
let ticks = 0; | ||
return new Promise<string>((resolve, reject) => { | ||
this.logger.verbose( | ||
@@ -575,3 +577,2 @@ "PopupHandler.monitorPopupForHash - polling started" | ||
); | ||
this.cleanPopup(); | ||
clearInterval(intervalId); | ||
@@ -586,4 +587,3 @@ reject( | ||
let href = Constants.EMPTY_STRING; | ||
let serverResponseString = Constants.EMPTY_STRING; | ||
let href = ""; | ||
try { | ||
@@ -596,7 +596,2 @@ /* | ||
href = popupWindow.location.href; | ||
serverResponseString = | ||
this.extractServerResponseStringFromPopup( | ||
popupWindow, | ||
href | ||
); | ||
} catch (e) {} | ||
@@ -608,102 +603,23 @@ | ||
} | ||
clearInterval(intervalId); | ||
this.logger.verbose( | ||
"PopupHandler.monitorPopupForHash - popup window is on same origin as caller" | ||
); | ||
/* | ||
* Only run clock when we are on same domain for popups | ||
* as popup operations can take a long time. | ||
*/ | ||
ticks++; | ||
if (serverResponseString) { | ||
this.logger.verbose( | ||
"PopupHandler.monitorPopupForHash - found hash in url" | ||
); | ||
clearInterval(intervalId); | ||
this.cleanPopup(popupWindow); | ||
if ( | ||
UrlString.hashContainsKnownProperties( | ||
serverResponseString | ||
) | ||
) { | ||
this.logger.verbose( | ||
"PopupHandler.monitorPopupForHash - hash contains known properties, returning." | ||
); | ||
resolve(serverResponseString); | ||
let responseString = ""; | ||
const responseType = | ||
this.config.auth.OIDCOptions.serverResponseType; | ||
if (popupWindow) { | ||
if (responseType === ServerResponseType.QUERY) { | ||
responseString = popupWindow.location.search; | ||
} else { | ||
this.logger.error( | ||
"PopupHandler.monitorPopupForHash - found hash in url but it does not contain known properties. Check that your router is not changing the hash prematurely." | ||
); | ||
this.logger.errorPii( | ||
`PopupHandler.monitorPopupForHash - hash found: ${serverResponseString}` | ||
); | ||
reject( | ||
createBrowserAuthError( | ||
BrowserAuthErrorCodes.hashDoesNotContainKnownProperties | ||
) | ||
); | ||
responseString = popupWindow.location.hash; | ||
} | ||
} else if (ticks > maxTicks) { | ||
this.logger.error( | ||
"PopupHandler.monitorPopupForHash - unable to find hash in url, timing out" | ||
); | ||
clearInterval(intervalId); | ||
reject( | ||
createBrowserAuthError( | ||
BrowserAuthErrorCodes.monitorPopupTimeout | ||
) | ||
); | ||
} | ||
}, this.config.system.pollIntervalMilliseconds); | ||
}); | ||
} | ||
/** | ||
* Waits for user interaction in logout popup window | ||
* @param popupWindow | ||
* @returns | ||
*/ | ||
waitForLogoutPopup(popupWindow: Window): Promise<void> { | ||
return new Promise((resolve) => { | ||
this.logger.verbose( | ||
"PopupHandler.waitForLogoutPopup - polling started" | ||
); | ||
const intervalId = setInterval(() => { | ||
// Window is closed | ||
if (popupWindow.closed) { | ||
this.logger.error( | ||
"PopupHandler.waitForLogoutPopup - window closed" | ||
); | ||
this.cleanPopup(); | ||
clearInterval(intervalId); | ||
resolve(); | ||
} | ||
let href: string = Constants.EMPTY_STRING; | ||
try { | ||
/* | ||
* Will throw if cross origin, | ||
* which should be caught and ignored | ||
* since we need the interval to keep running while on STS UI. | ||
*/ | ||
href = popupWindow.location.href; | ||
} catch (e) {} | ||
// Don't process blank pages or cross domain | ||
if (!href || href === "about:blank") { | ||
return; | ||
} | ||
this.logger.verbose( | ||
"PopupHandler.waitForLogoutPopup - popup window is on same origin as caller, closing." | ||
"PopupHandler.monitorPopupForHash - popup window is on same origin as caller" | ||
); | ||
clearInterval(intervalId); | ||
this.cleanPopup(popupWindow); | ||
resolve(); | ||
resolve(responseString); | ||
}, this.config.system.pollIntervalMilliseconds); | ||
}).finally(() => { | ||
this.cleanPopup(popupWindow); | ||
}); | ||
@@ -898,21 +814,2 @@ } | ||
} | ||
/** | ||
* Extracts the server response from the popup window | ||
*/ | ||
extractServerResponseStringFromPopup( | ||
popupWindow: Window, | ||
href: string | ||
): string { | ||
let serverResponseString; | ||
if ( | ||
this.config.auth.OIDCOptions?.serverResponseType === | ||
ServerResponseType.QUERY | ||
) { | ||
serverResponseString = UrlString.parseQueryServerResponse(href); | ||
} else { | ||
serverResponseString = popupWindow.location.hash; | ||
} | ||
return serverResponseString; | ||
} | ||
} |
@@ -22,2 +22,4 @@ /* | ||
invokeAsync, | ||
ServerResponseType, | ||
UrlUtils, | ||
} from "@azure/msal-common"; | ||
@@ -48,2 +50,3 @@ import { StandardInteractionClient } from "./StandardInteractionClient"; | ||
import { AuthenticationResult } from "../response/AuthenticationResult"; | ||
import * as ResponseHandler from "../response/ResponseHandler"; | ||
@@ -206,9 +209,9 @@ export class RedirectClient extends StandardInteractionClient { | ||
} | ||
const responseHash = this.getRedirectResponseHash( | ||
hash || window.location.hash | ||
const [serverParams, responseString] = this.getRedirectResponse( | ||
hash || "" | ||
); | ||
if (!responseHash) { | ||
if (!serverParams) { | ||
// Not a recognized server response hash or hash not associated with a redirect request | ||
this.logger.info( | ||
"handleRedirectPromise did not detect a response hash as a result of a redirect. Cleaning temporary cache." | ||
"handleRedirectPromise did not detect a response as a result of a redirect. Cleaning temporary cache." | ||
); | ||
@@ -221,22 +224,2 @@ this.browserStorage.cleanRequestByInteractionType( | ||
let state: string; | ||
try { | ||
// Deserialize hash fragment response parameters. | ||
const serverParams: ServerAuthorizationCodeResponse = | ||
UrlString.getDeserializedHash(responseHash); | ||
state = this.validateAndExtractStateFromHash( | ||
serverParams, | ||
InteractionType.Redirect | ||
); | ||
this.logger.verbose("State extracted from hash"); | ||
} catch (e) { | ||
this.logger.info( | ||
`handleRedirectPromise was unable to extract state due to: ${e}` | ||
); | ||
this.browserStorage.cleanRequestByInteractionType( | ||
InteractionType.Redirect | ||
); | ||
return null; | ||
} | ||
// If navigateToLoginRequestUrl is true, get the url where the redirect request was initiated | ||
@@ -260,9 +243,4 @@ const loginRequestUrl = | ||
this.logger.verbose( | ||
"Current page is loginRequestUrl, handling hash" | ||
"Current page is loginRequestUrl, handling response" | ||
); | ||
const handleHashResult = await this.handleHash( | ||
responseHash, | ||
state, | ||
serverTelemetryManager | ||
); | ||
@@ -274,10 +252,14 @@ if (loginRequestUrl.indexOf("#") > -1) { | ||
const handleHashResult = await this.handleResponse( | ||
serverParams, | ||
serverTelemetryManager | ||
); | ||
return handleHashResult; | ||
} else if (!this.config.auth.navigateToLoginRequestUrl) { | ||
this.logger.verbose( | ||
"NavigateToLoginRequestUrl set to false, handling hash" | ||
"NavigateToLoginRequestUrl set to false, handling response" | ||
); | ||
return this.handleHash( | ||
responseHash, | ||
state, | ||
return this.handleResponse( | ||
serverParams, | ||
serverTelemetryManager | ||
@@ -295,3 +277,3 @@ ); | ||
TemporaryCacheKeys.URL_HASH, | ||
responseHash, | ||
responseString, | ||
true | ||
@@ -341,5 +323,4 @@ ); | ||
if (!processHashOnRedirect) { | ||
return this.handleHash( | ||
responseHash, | ||
state, | ||
return this.handleResponse( | ||
serverParams, | ||
serverTelemetryManager | ||
@@ -368,9 +349,36 @@ ); | ||
*/ | ||
protected getRedirectResponseHash(hash: string): string | null { | ||
protected getRedirectResponse( | ||
userProvidedResponse: string | ||
): [ServerAuthorizationCodeResponse | null, string] { | ||
this.logger.verbose("getRedirectResponseHash called"); | ||
// Get current location hash from window or cache. | ||
const isResponseHash: boolean = | ||
UrlString.hashContainsKnownProperties(hash); | ||
let responseString = userProvidedResponse; | ||
if (!responseString) { | ||
if ( | ||
this.config.auth.OIDCOptions.serverResponseType === | ||
ServerResponseType.QUERY | ||
) { | ||
responseString = window.location.search; | ||
} else { | ||
responseString = window.location.hash; | ||
} | ||
} | ||
let response = UrlUtils.getDeserializedResponse(responseString); | ||
if (isResponseHash) { | ||
if (response) { | ||
try { | ||
ResponseHandler.validateInteractionType( | ||
response, | ||
this.browserCrypto, | ||
InteractionType.Redirect | ||
); | ||
} catch (e) { | ||
if (e instanceof AuthError) { | ||
this.logger.error( | ||
`Interaction type validation failed due to ${e.errorCode}: ${e.errorMessage}` | ||
); | ||
} | ||
return [null, ""]; | ||
} | ||
BrowserUtils.clearHash(window); | ||
@@ -380,3 +388,3 @@ this.logger.verbose( | ||
); | ||
return hash; | ||
return [response, responseString]; | ||
} | ||
@@ -392,6 +400,13 @@ | ||
this.logger.verbose( | ||
"Hash does not contain known properties, returning cached hash" | ||
); | ||
return cachedHash; | ||
if (cachedHash) { | ||
response = UrlUtils.getDeserializedResponse(cachedHash); | ||
if (response) { | ||
this.logger.verbose( | ||
"Hash does not contain known properties, returning cached hash" | ||
); | ||
return [response, cachedHash]; | ||
} | ||
} | ||
return [null, ""]; | ||
} | ||
@@ -404,13 +419,14 @@ | ||
*/ | ||
protected async handleHash( | ||
hash: string, | ||
state: string, | ||
protected async handleResponse( | ||
serverParams: ServerAuthorizationCodeResponse, | ||
serverTelemetryManager: ServerTelemetryManager | ||
): Promise<AuthenticationResult> { | ||
const state = serverParams.state; | ||
if (!state) { | ||
throw createBrowserAuthError(BrowserAuthErrorCodes.noStateInHash); | ||
} | ||
const cachedRequest = this.browserStorage.getCachedRequest(state); | ||
this.logger.verbose("handleHash called, retrieved cached request"); | ||
this.logger.verbose("handleResponse called, retrieved cached request"); | ||
const serverParams: ServerAuthorizationCodeResponse = | ||
UrlString.getDeserializedHash(hash); | ||
if (serverParams.accountId) { | ||
@@ -482,3 +498,3 @@ this.logger.verbose( | ||
); | ||
return await interactionHandler.handleCodeResponseFromHash(hash, state); | ||
return await interactionHandler.handleCodeResponse(serverParams, state); | ||
} | ||
@@ -485,0 +501,0 @@ |
@@ -13,4 +13,2 @@ /* | ||
AuthError, | ||
UrlString, | ||
ServerAuthorizationCodeResponse, | ||
ProtocolUtils, | ||
@@ -20,2 +18,3 @@ IPerformanceClient, | ||
invokeAsync, | ||
invoke, | ||
} from "@azure/msal-common"; | ||
@@ -43,2 +42,3 @@ import { StandardInteractionClient } from "./StandardInteractionClient"; | ||
import * as BrowserUtils from "../utils/BrowserUtils"; | ||
import * as ResponseHandler from "../response/ResponseHandler"; | ||
@@ -237,4 +237,5 @@ export class SilentIframeClient extends StandardInteractionClient { | ||
); | ||
const responseType = this.config.auth.OIDCOptions.serverResponseType; | ||
// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds. | ||
const hash = await invokeAsync( | ||
const responseString = await invokeAsync( | ||
monitorIframeForHash, | ||
@@ -251,22 +252,12 @@ PerformanceEvents.SilentHandlerMonitorIframeForHash, | ||
this.logger, | ||
correlationId | ||
correlationId, | ||
responseType | ||
); | ||
if (!hash) { | ||
// No hash is present | ||
this.logger.error( | ||
"The request has returned to the redirectUri but a hash is not present in the iframe. It's likely that the hash has been removed or the page has been redirected by code running on the redirectUri page." | ||
); | ||
throw createBrowserAuthError(BrowserAuthErrorCodes.hashEmptyError); | ||
} else if (!UrlString.hashContainsKnownProperties(hash)) { | ||
this.logger.error( | ||
"A hash is present in the iframe but it does not contain known properties. It's likely that the hash has been replaced by code running on the redirectUri page." | ||
); | ||
this.logger.errorPii(`The hash detected in the iframe is: ${hash}`); | ||
throw createBrowserAuthError( | ||
BrowserAuthErrorCodes.hashDoesNotContainKnownProperties | ||
); | ||
} | ||
// Deserialize hash fragment response parameters. | ||
const serverParams: ServerAuthorizationCodeResponse = | ||
UrlString.getDeserializedHash(hash); | ||
const serverParams = invoke( | ||
ResponseHandler.deserializeResponse, | ||
PerformanceEvents.DeserializeResponse, | ||
this.logger, | ||
this.performanceClient, | ||
this.correlationId | ||
)(responseString, responseType, this.logger); | ||
@@ -317,11 +308,9 @@ if (serverParams.accountId) { | ||
return invokeAsync( | ||
interactionHandler.handleCodeResponseFromHash.bind( | ||
interactionHandler | ||
), | ||
PerformanceEvents.HandleCodeResponseFromHash, | ||
interactionHandler.handleCodeResponse.bind(interactionHandler), | ||
PerformanceEvents.HandleCodeResponse, | ||
this.logger, | ||
this.performanceClient, | ||
correlationId | ||
)(hash, silentRequest); | ||
)(serverParams, silentRequest); | ||
} | ||
} |
@@ -15,3 +15,2 @@ /* | ||
AuthorityFactory, | ||
ServerAuthorizationCodeResponse, | ||
UrlString, | ||
@@ -32,10 +31,3 @@ CommonEndSessionRequest, | ||
import { version } from "../packageMetadata"; | ||
import { | ||
createBrowserAuthError, | ||
BrowserAuthErrorCodes, | ||
} from "../error/BrowserAuthError"; | ||
import { | ||
BrowserProtocolUtils, | ||
BrowserStateObject, | ||
} from "../utils/BrowserProtocolUtils"; | ||
import { BrowserStateObject } from "../utils/BrowserProtocolUtils"; | ||
import { EndSessionRequest } from "../request/EndSessionRequest"; | ||
@@ -62,3 +54,3 @@ import * as BrowserUtils from "../utils/BrowserUtils"; | ||
PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest, | ||
request.correlationId | ||
this.correlationId | ||
); | ||
@@ -301,40 +293,2 @@ const generatedPkceParams = await invokeAsync( | ||
/** | ||
* @param hash | ||
* @param interactionType | ||
*/ | ||
protected validateAndExtractStateFromHash( | ||
serverParams: ServerAuthorizationCodeResponse, | ||
interactionType: InteractionType, | ||
requestCorrelationId?: string | ||
): string { | ||
this.logger.verbose( | ||
"validateAndExtractStateFromHash called", | ||
requestCorrelationId | ||
); | ||
if (!serverParams.state) { | ||
throw createBrowserAuthError(BrowserAuthErrorCodes.noStateInHash); | ||
} | ||
const platformStateObj = | ||
BrowserProtocolUtils.extractBrowserRequestState( | ||
this.browserCrypto, | ||
serverParams.state | ||
); | ||
if (!platformStateObj) { | ||
throw createBrowserAuthError( | ||
BrowserAuthErrorCodes.unableToParseState | ||
); | ||
} | ||
if (platformStateObj.interactionType !== interactionType) { | ||
throw createBrowserAuthError( | ||
BrowserAuthErrorCodes.stateInteractionTypeMismatch | ||
); | ||
} | ||
this.logger.verbose("Returning state from hash", requestCorrelationId); | ||
return serverParams.state; | ||
} | ||
/** | ||
* Used to get a discovered version of the default authority. | ||
@@ -341,0 +295,0 @@ * @param requestAuthority |
@@ -17,2 +17,3 @@ /* | ||
CcsCredentialType, | ||
ServerAuthorizationCodeResponse, | ||
} from "@azure/msal-common"; | ||
@@ -56,14 +57,10 @@ | ||
*/ | ||
async handleCodeResponseFromHash( | ||
locationHash: string, | ||
async handleCodeResponse( | ||
response: ServerAuthorizationCodeResponse, | ||
request: AuthorizationUrlRequest | ||
): Promise<AuthenticationResult> { | ||
this.performanceClient.addQueueMeasurement( | ||
PerformanceEvents.HandleCodeResponseFromHash, | ||
PerformanceEvents.HandleCodeResponse, | ||
request.correlationId | ||
); | ||
// Check that location hash isn't empty. | ||
if (!locationHash) { | ||
throw createBrowserAuthError(BrowserAuthErrorCodes.hashEmptyError); | ||
} | ||
@@ -73,3 +70,3 @@ let authCodeResponse; | ||
authCodeResponse = this.authModule.handleFragmentResponse( | ||
locationHash, | ||
response, | ||
request.state | ||
@@ -76,0 +73,0 @@ ); |
@@ -17,2 +17,3 @@ /* | ||
PerformanceEvents, | ||
ServerAuthorizationCodeResponse, | ||
} from "@azure/msal-common"; | ||
@@ -145,4 +146,4 @@ import { | ||
*/ | ||
async handleCodeResponseFromHash( | ||
locationHash: string, | ||
async handleCodeResponse( | ||
response: ServerAuthorizationCodeResponse, | ||
state: string | ||
@@ -152,7 +153,2 @@ ): Promise<AuthenticationResult> { | ||
// Check that location hash isn't empty. | ||
if (!locationHash) { | ||
throw createBrowserAuthError(BrowserAuthErrorCodes.hashEmptyError); | ||
} | ||
// Interaction is completed - remove interaction status. | ||
@@ -174,3 +170,3 @@ this.browserStorage.setInteractionInProgress(false); | ||
authCodeResponse = this.authModule.handleFragmentResponse( | ||
locationHash, | ||
response, | ||
requestState | ||
@@ -177,0 +173,0 @@ ); |
@@ -12,2 +12,3 @@ /* | ||
invoke, | ||
ServerResponseType, | ||
} from "@azure/msal-common"; | ||
@@ -71,3 +72,4 @@ import { | ||
logger: Logger, | ||
correlationId: string | ||
correlationId: string, | ||
responseType: ServerResponseType | ||
): Promise<string> { | ||
@@ -115,8 +117,13 @@ performanceClient.addQueueMeasurement( | ||
const contentHash = contentWindow | ||
? contentWindow.location.hash | ||
: ""; | ||
let responseString = ""; | ||
if (contentWindow) { | ||
if (responseType === ServerResponseType.QUERY) { | ||
responseString = contentWindow.location.search; | ||
} else { | ||
responseString = contentWindow.location.hash; | ||
} | ||
} | ||
window.clearTimeout(timeoutId); | ||
window.clearInterval(intervalId); | ||
resolve(contentHash); | ||
resolve(responseString); | ||
}, pollIntervalMilliseconds); | ||
@@ -123,0 +130,0 @@ }).finally(() => { |
/* eslint-disable header/header */ | ||
export const name = "@azure/msal-browser"; | ||
export const version = "3.4.0"; | ||
export const version = "3.5.0"; |
@@ -11,4 +11,2 @@ /* | ||
ProtocolUtils, | ||
ServerAuthorizationCodeResponse, | ||
UrlString, | ||
createClientAuthError, | ||
@@ -22,39 +20,22 @@ ClientAuthErrorCodes, | ||
export class BrowserProtocolUtils { | ||
/** | ||
* Extracts the BrowserStateObject from the state string. | ||
* @param browserCrypto | ||
* @param state | ||
*/ | ||
static extractBrowserRequestState( | ||
browserCrypto: ICrypto, | ||
state: string | ||
): BrowserStateObject | null { | ||
if (!state) { | ||
return null; | ||
} | ||
try { | ||
const requestStateObj: RequestStateObject = | ||
ProtocolUtils.parseRequestState(browserCrypto, state); | ||
return requestStateObj.libraryState.meta as BrowserStateObject; | ||
} catch (e) { | ||
throw createClientAuthError(ClientAuthErrorCodes.invalidState); | ||
} | ||
/** | ||
* Extracts the BrowserStateObject from the state string. | ||
* @param browserCrypto | ||
* @param state | ||
*/ | ||
export function extractBrowserRequestState( | ||
browserCrypto: ICrypto, | ||
state: string | ||
): BrowserStateObject | null { | ||
if (!state) { | ||
return null; | ||
} | ||
/** | ||
* Parses properties of server response from url hash | ||
* @param locationHash Hash from url | ||
*/ | ||
static parseServerResponseFromHash( | ||
locationHash: string | ||
): ServerAuthorizationCodeResponse { | ||
if (!locationHash) { | ||
return {}; | ||
} | ||
const hashUrlString = new UrlString(locationHash); | ||
return UrlString.getDeserializedHash(hashUrlString.getHash()); | ||
try { | ||
const requestStateObj: RequestStateObject = | ||
ProtocolUtils.parseRequestState(browserCrypto, state); | ||
return requestStateObj.libraryState.meta as BrowserStateObject; | ||
} catch (e) { | ||
throw createClientAuthError(ClientAuthErrorCodes.invalidState); | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
418
4729468
68181
+ Added@azure/msal-common@14.4.0(transitive)
- Removed@azure/msal-common@14.3.0(transitive)
Updated@azure/msal-common@14.4.0