Commit iniziale

This commit is contained in:
Paolo A
2025-02-18 22:59:07 +00:00
commit 4bbf35cefb
6879 changed files with 623784 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
import { AuthorizationCodePayload, CommonAuthorizationCodeRequest, AuthorizationCodeClient, CcsCredential, Logger, IPerformanceClient, ServerAuthorizationCodeResponse } from "@azure/msal-common/browser";
import { BrowserCacheManager } from "../cache/BrowserCacheManager.js";
import { AuthenticationResult } from "../response/AuthenticationResult.js";
import { AuthorizationUrlRequest } from "../request/AuthorizationUrlRequest.js";
/**
* Abstract class which defines operations for a browser interaction handling class.
*/
export declare class InteractionHandler {
protected authModule: AuthorizationCodeClient;
protected browserStorage: BrowserCacheManager;
protected authCodeRequest: CommonAuthorizationCodeRequest;
protected logger: Logger;
protected performanceClient: IPerformanceClient;
constructor(authCodeModule: AuthorizationCodeClient, storageImpl: BrowserCacheManager, authCodeRequest: CommonAuthorizationCodeRequest, logger: Logger, performanceClient: IPerformanceClient);
/**
* Function to handle response parameters from hash.
* @param locationHash
*/
handleCodeResponse(response: ServerAuthorizationCodeResponse, request: AuthorizationUrlRequest): Promise<AuthenticationResult>;
/**
* Process auth code response from AAD
* @param authCodeResponse
* @param state
* @param authority
* @param networkModule
* @returns
*/
handleCodeResponseFromServer(authCodeResponse: AuthorizationCodePayload, request: AuthorizationUrlRequest, validateNonce?: boolean): Promise<AuthenticationResult>;
/**
* Build ccs creds if available
*/
protected createCcsCredentials(request: AuthorizationUrlRequest): CcsCredential | null;
}
//# sourceMappingURL=InteractionHandler.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"InteractionHandler.d.ts","sourceRoot":"","sources":["../../src/interaction_handler/InteractionHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,wBAAwB,EACxB,8BAA8B,EAC9B,uBAAuB,EACvB,aAAa,EACb,MAAM,EAEN,kBAAkB,EAIlB,+BAA+B,EAClC,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAKtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAEhF;;GAEG;AACH,qBAAa,kBAAkB;IAC3B,SAAS,CAAC,UAAU,EAAE,uBAAuB,CAAC;IAC9C,SAAS,CAAC,cAAc,EAAE,mBAAmB,CAAC;IAC9C,SAAS,CAAC,eAAe,EAAE,8BAA8B,CAAC;IAC1D,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;gBAG5C,cAAc,EAAE,uBAAuB,EACvC,WAAW,EAAE,mBAAmB,EAChC,eAAe,EAAE,8BAA8B,EAC/C,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,kBAAkB;IASzC;;;OAGG;IACG,kBAAkB,CACpB,QAAQ,EAAE,+BAA+B,EACzC,OAAO,EAAE,uBAAuB,GACjC,OAAO,CAAC,oBAAoB,CAAC;IAmChC;;;;;;;OAOG;IACG,4BAA4B,CAC9B,gBAAgB,EAAE,wBAAwB,EAC1C,OAAO,EAAE,uBAAuB,EAChC,aAAa,GAAE,OAAc,GAC9B,OAAO,CAAC,oBAAoB,CAAC;IAoDhC;;OAEG;IACH,SAAS,CAAC,oBAAoB,CAC1B,OAAO,EAAE,uBAAuB,GACjC,aAAa,GAAG,IAAI;CAe1B"}

View File

@@ -0,0 +1,102 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { PerformanceEvents, ServerError, invokeAsync, CcsCredentialType } from '@azure/msal-common/browser';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { userCancelled } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Abstract class which defines operations for a browser interaction handling class.
*/
class InteractionHandler {
constructor(authCodeModule, storageImpl, authCodeRequest, logger, performanceClient) {
this.authModule = authCodeModule;
this.browserStorage = storageImpl;
this.authCodeRequest = authCodeRequest;
this.logger = logger;
this.performanceClient = performanceClient;
}
/**
* Function to handle response parameters from hash.
* @param locationHash
*/
async handleCodeResponse(response, request) {
this.performanceClient.addQueueMeasurement(PerformanceEvents.HandleCodeResponse, request.correlationId);
let authCodeResponse;
try {
authCodeResponse = this.authModule.handleFragmentResponse(response, request.state);
}
catch (e) {
if (e instanceof ServerError &&
e.subError === userCancelled) {
// Translate server error caused by user closing native prompt to corresponding first class MSAL error
throw createBrowserAuthError(userCancelled);
}
else {
throw e;
}
}
return invokeAsync(this.handleCodeResponseFromServer.bind(this), PerformanceEvents.HandleCodeResponseFromServer, this.logger, this.performanceClient, request.correlationId)(authCodeResponse, request);
}
/**
* Process auth code response from AAD
* @param authCodeResponse
* @param state
* @param authority
* @param networkModule
* @returns
*/
async handleCodeResponseFromServer(authCodeResponse, request, validateNonce = true) {
this.performanceClient.addQueueMeasurement(PerformanceEvents.HandleCodeResponseFromServer, request.correlationId);
this.logger.trace("InteractionHandler.handleCodeResponseFromServer called");
// Assign code to request
this.authCodeRequest.code = authCodeResponse.code;
// Check for new cloud instance
if (authCodeResponse.cloud_instance_host_name) {
await invokeAsync(this.authModule.updateAuthority.bind(this.authModule), PerformanceEvents.UpdateTokenEndpointAuthority, this.logger, this.performanceClient, request.correlationId)(authCodeResponse.cloud_instance_host_name, request.correlationId);
}
// Nonce validation not needed when redirect not involved (e.g. hybrid spa, renewing token via rt)
if (validateNonce) {
// TODO: Assigning "response nonce" to "request nonce" is confusing. Refactor the function doing validation to accept request nonce directly
authCodeResponse.nonce = request.nonce || undefined;
}
authCodeResponse.state = request.state;
// Add CCS parameters if available
if (authCodeResponse.client_info) {
this.authCodeRequest.clientInfo = authCodeResponse.client_info;
}
else {
const ccsCred = this.createCcsCredentials(request);
if (ccsCred) {
this.authCodeRequest.ccsCredential = ccsCred;
}
}
// Acquire token with retrieved code.
const tokenResponse = (await invokeAsync(this.authModule.acquireToken.bind(this.authModule), PerformanceEvents.AuthClientAcquireToken, this.logger, this.performanceClient, request.correlationId)(this.authCodeRequest, authCodeResponse));
return tokenResponse;
}
/**
* Build ccs creds if available
*/
createCcsCredentials(request) {
if (request.account) {
return {
credential: request.account.homeAccountId,
type: CcsCredentialType.HOME_ACCOUNT_ID,
};
}
else if (request.loginHint) {
return {
credential: request.loginHint,
type: CcsCredentialType.UPN,
};
}
return null;
}
}
export { InteractionHandler };
//# sourceMappingURL=InteractionHandler.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"InteractionHandler.mjs","sources":["../../src/interaction_handler/InteractionHandler.ts"],"sourcesContent":[null],"names":["BrowserAuthErrorCodes.userCancelled"],"mappings":"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"}

View File

@@ -0,0 +1,33 @@
import { AuthorizationCodeClient, CommonAuthorizationCodeRequest, Logger, IPerformanceClient, CcsCredential, ServerAuthorizationCodeResponse } from "@azure/msal-common/browser";
import { BrowserCacheManager } from "../cache/BrowserCacheManager.js";
import { INavigationClient } from "../navigation/INavigationClient.js";
import { AuthenticationResult } from "../response/AuthenticationResult.js";
export type RedirectParams = {
navigationClient: INavigationClient;
redirectTimeout: number;
redirectStartPage: string;
onRedirectNavigate?: (url: string) => void | boolean;
};
export declare class RedirectHandler {
authModule: AuthorizationCodeClient;
browserStorage: BrowserCacheManager;
authCodeRequest: CommonAuthorizationCodeRequest;
logger: Logger;
performanceClient: IPerformanceClient;
constructor(authCodeModule: AuthorizationCodeClient, storageImpl: BrowserCacheManager, authCodeRequest: CommonAuthorizationCodeRequest, logger: Logger, performanceClient: IPerformanceClient);
/**
* Redirects window to given URL.
* @param urlNavigate
*/
initiateAuthRequest(requestUrl: string, params: RedirectParams): Promise<void>;
/**
* Handle authorization code response in the window.
* @param hash
*/
handleCodeResponse(response: ServerAuthorizationCodeResponse, state: string): Promise<AuthenticationResult>;
/**
* Looks up ccs creds in the cache
*/
protected checkCcsCredentials(): CcsCredential | null;
}
//# sourceMappingURL=RedirectHandler.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"RedirectHandler.d.ts","sourceRoot":"","sources":["../../src/interaction_handler/RedirectHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,uBAAuB,EACvB,8BAA8B,EAC9B,MAAM,EAEN,kBAAkB,EAGlB,aAAa,EAGb,+BAA+B,EAClC,MAAM,4BAA4B,CAAC;AAMpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAEvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,MAAM,MAAM,cAAc,GAAG;IACzB,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;CACxD,CAAC;AAEF,qBAAa,eAAe;IACxB,UAAU,EAAE,uBAAuB,CAAC;IACpC,cAAc,EAAE,mBAAmB,CAAC;IACpC,eAAe,EAAE,8BAA8B,CAAC;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,kBAAkB,CAAC;gBAGlC,cAAc,EAAE,uBAAuB,EACvC,WAAW,EAAE,mBAAmB,EAChC,eAAe,EAAE,8BAA8B,EAC/C,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,kBAAkB;IASzC;;;OAGG;IACG,mBAAmB,CACrB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IA6EhB;;;OAGG;IACG,kBAAkB,CACpB,QAAQ,EAAE,+BAA+B,EACzC,KAAK,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC;IAgFhC;;OAEG;IACH,SAAS,CAAC,mBAAmB,IAAI,aAAa,GAAG,IAAI;CAoBxD"}

View File

@@ -0,0 +1,144 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { createClientAuthError, ClientAuthErrorCodes, ServerError, invokeAsync, PerformanceEvents } from '@azure/msal-common/browser';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { TemporaryCacheKeys, ApiId } from '../utils/BrowserConstants.mjs';
import { emptyNavigateUri, userCancelled } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class RedirectHandler {
constructor(authCodeModule, storageImpl, authCodeRequest, logger, performanceClient) {
this.authModule = authCodeModule;
this.browserStorage = storageImpl;
this.authCodeRequest = authCodeRequest;
this.logger = logger;
this.performanceClient = performanceClient;
}
/**
* Redirects window to given URL.
* @param urlNavigate
*/
async initiateAuthRequest(requestUrl, params) {
this.logger.verbose("RedirectHandler.initiateAuthRequest called");
// Navigate if valid URL
if (requestUrl) {
// Cache start page, returns to this page after redirectUri if navigateToLoginRequestUrl is true
if (params.redirectStartPage) {
this.logger.verbose("RedirectHandler.initiateAuthRequest: redirectStartPage set, caching start page");
this.browserStorage.setTemporaryCache(TemporaryCacheKeys.ORIGIN_URI, params.redirectStartPage, true);
}
// Set interaction status in the library.
this.browserStorage.setTemporaryCache(TemporaryCacheKeys.CORRELATION_ID, this.authCodeRequest.correlationId, true);
this.browserStorage.cacheCodeRequest(this.authCodeRequest);
this.logger.infoPii(`RedirectHandler.initiateAuthRequest: Navigate to: ${requestUrl}`);
const navigationOptions = {
apiId: ApiId.acquireTokenRedirect,
timeout: params.redirectTimeout,
noHistory: false,
};
// If onRedirectNavigate is implemented, invoke it and provide requestUrl
if (typeof params.onRedirectNavigate === "function") {
this.logger.verbose("RedirectHandler.initiateAuthRequest: Invoking onRedirectNavigate callback");
const navigate = params.onRedirectNavigate(requestUrl);
// Returning false from onRedirectNavigate will stop navigation
if (navigate !== false) {
this.logger.verbose("RedirectHandler.initiateAuthRequest: onRedirectNavigate did not return false, navigating");
await params.navigationClient.navigateExternal(requestUrl, navigationOptions);
return;
}
else {
this.logger.verbose("RedirectHandler.initiateAuthRequest: onRedirectNavigate returned false, stopping navigation");
return;
}
}
else {
// Navigate window to request URL
this.logger.verbose("RedirectHandler.initiateAuthRequest: Navigating window to navigate url");
await params.navigationClient.navigateExternal(requestUrl, navigationOptions);
return;
}
}
else {
// Throw error if request URL is empty.
this.logger.info("RedirectHandler.initiateAuthRequest: Navigate url is empty");
throw createBrowserAuthError(emptyNavigateUri);
}
}
/**
* Handle authorization code response in the window.
* @param hash
*/
async handleCodeResponse(response, state) {
this.logger.verbose("RedirectHandler.handleCodeResponse called");
// Interaction is completed - remove interaction status.
this.browserStorage.setInteractionInProgress(false);
// Handle code response.
const stateKey = this.browserStorage.generateStateKey(state);
const requestState = this.browserStorage.getTemporaryCache(stateKey);
if (!requestState) {
throw createClientAuthError(ClientAuthErrorCodes.stateNotFound, "Cached State");
}
let authCodeResponse;
try {
authCodeResponse = this.authModule.handleFragmentResponse(response, requestState);
}
catch (e) {
if (e instanceof ServerError &&
e.subError === userCancelled) {
// Translate server error caused by user closing native prompt to corresponding first class MSAL error
throw createBrowserAuthError(userCancelled);
}
else {
throw e;
}
}
// Get cached items
const nonceKey = this.browserStorage.generateNonceKey(requestState);
const cachedNonce = this.browserStorage.getTemporaryCache(nonceKey);
// Assign code to request
this.authCodeRequest.code = authCodeResponse.code;
// Check for new cloud instance
if (authCodeResponse.cloud_instance_host_name) {
await invokeAsync(this.authModule.updateAuthority.bind(this.authModule), PerformanceEvents.UpdateTokenEndpointAuthority, this.logger, this.performanceClient, this.authCodeRequest.correlationId)(authCodeResponse.cloud_instance_host_name, this.authCodeRequest.correlationId);
}
authCodeResponse.nonce = cachedNonce || undefined;
authCodeResponse.state = requestState;
// Add CCS parameters if available
if (authCodeResponse.client_info) {
this.authCodeRequest.clientInfo = authCodeResponse.client_info;
}
else {
const cachedCcsCred = this.checkCcsCredentials();
if (cachedCcsCred) {
this.authCodeRequest.ccsCredential = cachedCcsCred;
}
}
// Acquire token with retrieved code.
const tokenResponse = (await this.authModule.acquireToken(this.authCodeRequest, authCodeResponse));
this.browserStorage.cleanRequestByState(state);
return tokenResponse;
}
/**
* Looks up ccs creds in the cache
*/
checkCcsCredentials() {
// Look up ccs credential in temp cache
const cachedCcsCred = this.browserStorage.getTemporaryCache(TemporaryCacheKeys.CCS_CREDENTIAL, true);
if (cachedCcsCred) {
try {
return JSON.parse(cachedCcsCred);
}
catch (e) {
this.authModule.logger.error("Cache credential could not be parsed");
this.authModule.logger.errorPii(`Cache credential could not be parsed: ${cachedCcsCred}`);
}
}
return null;
}
}
export { RedirectHandler };
//# sourceMappingURL=RedirectHandler.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"RedirectHandler.mjs","sources":["../../src/interaction_handler/RedirectHandler.ts"],"sourcesContent":[null],"names":["BrowserAuthErrorCodes.emptyNavigateUri","BrowserAuthErrorCodes.userCancelled"],"mappings":"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"}

View File

@@ -0,0 +1,14 @@
import { Logger, IPerformanceClient, ServerResponseType } from "@azure/msal-common/browser";
/**
* Creates a hidden iframe to given URL using user-requested scopes as an id.
* @param urlNavigate
* @param userRequestScopes
*/
export declare function initiateAuthRequest(requestUrl: string, performanceClient: IPerformanceClient, logger: Logger, correlationId: string, navigateFrameWait?: number): Promise<HTMLIFrameElement>;
/**
* Monitors an iframe content window until it loads a url with a known hash, or hits a specified timeout.
* @param iframe
* @param timeout
*/
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

View File

@@ -0,0 +1 @@
{"version":3,"file":"SilentHandler.d.ts","sourceRoot":"","sources":["../../src/interaction_handler/SilentHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,MAAM,EACN,kBAAkB,EAIlB,kBAAkB,EACrB,MAAM,4BAA4B,CAAC;AAOpC;;;;GAIG;AACH,wBAAsB,mBAAmB,CACrC,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,kBAAkB,EACrC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,iBAAiB,CAAC,EAAE,MAAM,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CA2B5B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACtC,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,MAAM,EACf,wBAAwB,EAAE,MAAM,EAChC,iBAAiB,EAAE,kBAAkB,EACrC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,kBAAkB,GACjC,OAAO,CAAC,MAAM,CAAC,CA+DjB"}

View File

@@ -0,0 +1,144 @@
/*! @azure/msal-browser v4.2.1 2025-02-11 */
'use strict';
import { PerformanceEvents, invokeAsync, invoke, ServerResponseType } from '@azure/msal-common/browser';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { DEFAULT_IFRAME_TIMEOUT_MS } from '../config/Configuration.mjs';
import { emptyNavigateUri, monitorWindowTimeout } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Creates a hidden iframe to given URL using user-requested scopes as an id.
* @param urlNavigate
* @param userRequestScopes
*/
async function initiateAuthRequest(requestUrl, performanceClient, logger, correlationId, navigateFrameWait) {
performanceClient.addQueueMeasurement(PerformanceEvents.SilentHandlerInitiateAuthRequest, correlationId);
if (!requestUrl) {
// Throw error if request URL is empty.
logger.info("Navigate url is empty");
throw createBrowserAuthError(emptyNavigateUri);
}
if (navigateFrameWait) {
return invokeAsync(loadFrame, PerformanceEvents.SilentHandlerLoadFrame, logger, performanceClient, correlationId)(requestUrl, navigateFrameWait, performanceClient, correlationId);
}
return invoke(loadFrameSync, PerformanceEvents.SilentHandlerLoadFrameSync, logger, performanceClient, correlationId)(requestUrl);
}
/**
* Monitors an iframe content window until it loads a url with a known hash, or hits a specified timeout.
* @param iframe
* @param timeout
*/
async function monitorIframeForHash(iframe, timeout, pollIntervalMilliseconds, performanceClient, logger, correlationId, responseType) {
performanceClient.addQueueMeasurement(PerformanceEvents.SilentHandlerMonitorIframeForHash, correlationId);
return new Promise((resolve, reject) => {
if (timeout < DEFAULT_IFRAME_TIMEOUT_MS) {
logger.warning(`system.loadFrameTimeout or system.iframeHashTimeout set to lower (${timeout}ms) than the default (${DEFAULT_IFRAME_TIMEOUT_MS}ms). This may result in timeouts.`);
}
/*
* Polling for iframes can be purely timing based,
* since we don't need to account for interaction.
*/
const timeoutId = window.setTimeout(() => {
window.clearInterval(intervalId);
reject(createBrowserAuthError(monitorWindowTimeout));
}, timeout);
const intervalId = window.setInterval(() => {
let href = "";
const contentWindow = iframe.contentWindow;
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 = contentWindow ? contentWindow.location.href : "";
}
catch (e) { }
if (!href || href === "about:blank") {
return;
}
let responseString = "";
if (contentWindow) {
if (responseType === ServerResponseType.QUERY) {
responseString = contentWindow.location.search;
}
else {
responseString = contentWindow.location.hash;
}
}
window.clearTimeout(timeoutId);
window.clearInterval(intervalId);
resolve(responseString);
}, pollIntervalMilliseconds);
}).finally(() => {
invoke(removeHiddenIframe, PerformanceEvents.RemoveHiddenIframe, logger, performanceClient, correlationId)(iframe);
});
}
/**
* @hidden
* Loads iframe with authorization endpoint URL
* @ignore
* @deprecated
*/
function loadFrame(urlNavigate, navigateFrameWait, performanceClient, correlationId) {
performanceClient.addQueueMeasurement(PerformanceEvents.SilentHandlerLoadFrame, correlationId);
/*
* This trick overcomes iframe navigation in IE
* IE does not load the page consistently in iframe
*/
return new Promise((resolve, reject) => {
const frameHandle = createHiddenIframe();
window.setTimeout(() => {
if (!frameHandle) {
reject("Unable to load iframe");
return;
}
frameHandle.src = urlNavigate;
resolve(frameHandle);
}, navigateFrameWait);
});
}
/**
* @hidden
* Loads the iframe synchronously when the navigateTimeFrame is set to `0`
* @param urlNavigate
* @param frameName
* @param logger
*/
function loadFrameSync(urlNavigate) {
const frameHandle = createHiddenIframe();
frameHandle.src = urlNavigate;
return frameHandle;
}
/**
* @hidden
* Creates a new hidden iframe or gets an existing one for silent token renewal.
* @ignore
*/
function createHiddenIframe() {
const authFrame = document.createElement("iframe");
authFrame.className = "msalSilentIframe";
authFrame.style.visibility = "hidden";
authFrame.style.position = "absolute";
authFrame.style.width = authFrame.style.height = "0";
authFrame.style.border = "0";
authFrame.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
document.body.appendChild(authFrame);
return authFrame;
}
/**
* @hidden
* Removes a hidden iframe from the page.
* @ignore
*/
function removeHiddenIframe(iframe) {
if (document.body === iframe.parentNode) {
document.body.removeChild(iframe);
}
}
export { initiateAuthRequest, monitorIframeForHash };
//# sourceMappingURL=SilentHandler.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SilentHandler.mjs","sources":["../../src/interaction_handler/SilentHandler.ts"],"sourcesContent":[null],"names":["BrowserAuthErrorCodes.emptyNavigateUri","BrowserAuthErrorCodes.monitorWindowTimeout"],"mappings":"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"}