Estructura inicial del proyecto

This commit is contained in:
2026-06-02 16:57:08 +00:00
commit 8b306b9afc
9864 changed files with 1435687 additions and 0 deletions

View File

@ -0,0 +1,143 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { ServerTelemetryManager, UrlString, Authority, invokeAsync, AuthorityFactory, createClientConfigurationError, ClientConfigurationErrorCodes } from '@azure/msal-common/browser';
import { AuthorityFactoryCreateDiscoveredInstance } from '../telemetry/BrowserPerformanceEvents.mjs';
import { version } from '../packageMetadata.mjs';
import { BrowserConstants } from '../utils/BrowserConstants.mjs';
import { getCurrentUri } from '../utils/BrowserUtils.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class BaseInteractionClient {
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, correlationId, platformAuthProvider) {
this.config = config;
this.browserStorage = storageImpl;
this.browserCrypto = browserCrypto;
this.networkClient = this.config.system.networkClient;
this.eventHandler = eventHandler;
this.navigationClient = navigationClient;
this.platformAuthProvider = platformAuthProvider;
this.correlationId = correlationId;
this.logger = logger.clone(BrowserConstants.MSAL_SKU, version);
this.performanceClient = performanceClient;
}
}
/**
* Use to get the redirect URI configured in MSAL or construct one from the current page.
* @param requestRedirectUri - Redirect URI from the request or undefined if not configured
* @param clientConfigRedirectUri - Redirect URI from the client configuration or undefined if not configured
* @param logger - Logger instance from the calling client
* @param correlationId
* @returns Absolute redirect URL constructed from the provided URI, config, or current page
*/
function getRedirectUri(requestRedirectUri, clientConfigRedirectUri, logger, correlationId) {
logger.verbose("0bd1la", correlationId);
const redirectUri = requestRedirectUri || clientConfigRedirectUri || "";
return UrlString.getAbsoluteUrl(redirectUri, getCurrentUri());
}
/**
* Initializes and returns a ServerTelemetryManager with the provided telemetry configuration.
* @param apiId - The API identifier for telemetry tracking
* @param clientId - The client application identifier
* @param correlationId - Unique identifier for correlating requests
* @param browserStorage - Browser cache manager instance for storing telemetry data
* @param logger - Optional logger instance for verbose logging
* @param forceRefresh - Optional flag to force refresh of telemetry data
* @returns Configured ServerTelemetryManager instance
*/
function initializeServerTelemetryManager(apiId, clientId, correlationId, browserStorage, logger, forceRefresh) {
logger.verbose("1p12tq", correlationId);
const telemetryPayload = {
clientId: clientId,
correlationId: correlationId,
apiId: apiId,
forceRefresh: forceRefresh || false,
wrapperSKU: browserStorage.getWrapperMetadata()[0],
wrapperVer: browserStorage.getWrapperMetadata()[1],
};
return new ServerTelemetryManager(telemetryPayload, browserStorage);
}
/**
* Used to get a discovered version of the default authority.
* @param params - Configuration object containing authority and cloud options
* @param params.requestAuthority - Optional specific authority URL to use
* @param params.requestAzureCloudOptions - Optional Azure cloud configuration options
* @param params.requestExtraQueryParameters - Optional additional query parameters
* @param params.account - Optional account info for instance-aware scenarios
* @param config - Browser configuration containing auth settings
* @param correlationId - Unique identifier for correlating requests
* @param performanceClient - Performance monitoring client instance
* @param browserStorage - Browser cache manager instance
* @param logger - Logger instance for tracking operations
* @returns Promise that resolves to a discovered Authority instance
*/
async function getDiscoveredAuthority(config, correlationId, performanceClient, browserStorage, logger, requestAuthority, requestAzureCloudOptions, requestExtraQueryParameters, account) {
const instanceAwareEQ = requestExtraQueryParameters &&
requestExtraQueryParameters.hasOwnProperty("instance_aware")
? requestExtraQueryParameters["instance_aware"]
: undefined;
const authorityOptions = {
protocolMode: config.system.protocolMode,
OIDCOptions: config.auth.OIDCOptions,
knownAuthorities: config.auth.knownAuthorities,
cloudDiscoveryMetadata: config.auth.cloudDiscoveryMetadata,
authorityMetadata: config.auth.authorityMetadata,
};
// build authority string based on auth params, precedence - azureCloudInstance + tenant >> authority
const resolvedAuthority = requestAuthority || config.auth.authority;
const resolvedInstanceAware = instanceAwareEQ?.length
? instanceAwareEQ === "true"
: config.auth.instanceAware;
const userAuthority = account && resolvedInstanceAware
? config.auth.authority.replace(UrlString.getDomainFromUrl(resolvedAuthority), account.environment)
: resolvedAuthority;
// fall back to the authority from config
const builtAuthority = Authority.generateAuthority(userAuthority, requestAzureCloudOptions || config.auth.azureCloudOptions);
const discoveredAuthority = await invokeAsync(AuthorityFactory.createDiscoveredInstance, AuthorityFactoryCreateDiscoveredInstance, logger, performanceClient, correlationId)(builtAuthority, config.system.networkClient, browserStorage, authorityOptions, logger, correlationId, performanceClient);
if (account && !discoveredAuthority.isAlias(account.environment)) {
throw createClientConfigurationError(ClientConfigurationErrorCodes.authorityMismatch);
}
return discoveredAuthority;
}
/**
* Clears cache and account information during logout.
*
* If an account is provided, removes the account from cache and, if it is the active account, sets the active account to null.
* If no account is provided, clears all accounts and tokens from cache.
*
* @param browserStorage - The browser cache manager instance used to manage cache.
* @param browserCrypto - The crypto interface for cache operations.
* @param logger - Logger instance for logging operations.
* @param correlationId - Correlation ID for the logout operation.
* @param account - (Optional) The account to clear from cache. If not provided, all accounts are cleared.
* @returns A promise that resolves when the cache has been cleared.
*/
async function clearCacheOnLogout(browserStorage, browserCrypto, logger, correlationId, account) {
if (account) {
// Clear given account.
try {
browserStorage.removeAccount(account, correlationId);
logger.verbose("0s4z6h", correlationId);
}
catch (error) {
logger.error("0mgg1d", correlationId);
}
}
else {
try {
logger.verbose("0zj631", correlationId);
// Clear all accounts and tokens
browserStorage.clear(correlationId);
// Clear any stray keys from IndexedDB
await browserCrypto.clearKeystore(correlationId);
}
catch (e) {
logger.error("12ih0c", correlationId);
}
}
}
export { BaseInteractionClient, clearCacheOnLogout, getDiscoveredAuthority, getRedirectUri, initializeServerTelemetryManager };
//# sourceMappingURL=BaseInteractionClient.mjs.map

View File

@ -0,0 +1 @@
{"version":3,"file":"BaseInteractionClient.mjs","sources":["../../src/interaction_client/BaseInteractionClient.ts"],"sourcesContent":[null],"names":["BrowserUtils.getCurrentUri","BrowserPerformanceEvents.AuthorityFactoryCreateDiscoveredInstance"],"mappings":"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"}

View File

@ -0,0 +1,17 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { AuthorizationCodeClient } from '@azure/msal-common/browser';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class HybridSpaAuthorizationCodeClient extends AuthorizationCodeClient {
constructor(config, performanceClient) {
super(config, performanceClient);
this.includeRedirectUri = false;
}
}
export { HybridSpaAuthorizationCodeClient };
//# sourceMappingURL=HybridSpaAuthorizationCodeClient.mjs.map

View File

@ -0,0 +1 @@
{"version":3,"file":"HybridSpaAuthorizationCodeClient.mjs","sources":["../../src/interaction_client/HybridSpaAuthorizationCodeClient.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAAA;;;AAGG;AAQG,MAAO,gCAAiC,SAAQ,uBAAuB,CAAA;IACzE,WACI,CAAA,MAA2B,EAC3B,iBAAqC,EAAA;AAErC,QAAA,KAAK,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AACjC,QAAA,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;KACnC;AACJ;;;;"}

View File

@ -0,0 +1,645 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { ServerTelemetryManager, AADServerParamKeys, TimeUtils, ScopeSet, createClientAuthError, ClientAuthErrorCodes, AuthToken, updateAccountTenantProfileData, buildAccountToCache, AccountEntityUtils, AuthorityType, Constants, PopTokenGenerator, CacheHelpers, RequestParameterBuilder, invokeAsync, PerformanceEvents, UrlString } from '@azure/msal-common/browser';
import { base64Decode } from '../encode/Base64Decode.mjs';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { NativeAuthError, isFatalNativeAuthError, createNativeAuthError } from '../error/NativeAuthError.mjs';
import { version } from '../packageMetadata.mjs';
import { NativeInteractionClientAcquireToken } from '../telemetry/BrowserPerformanceEvents.mjs';
import { BrowserConstants, CacheLookupPolicy, TemporaryCacheKeys, ApiId, PlatformAuthConstants } from '../utils/BrowserConstants.mjs';
import { BaseInteractionClient, initializeServerTelemetryManager, getRedirectUri, getDiscoveredAuthority } from './BaseInteractionClient.mjs';
import { SilentCacheClient } from './SilentCacheClient.mjs';
import { invalidPopTokenRequest, nativePromptNotSupported } from '../error/BrowserAuthErrorCodes.mjs';
import { userSwitch } from '../error/NativeAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class PlatformAuthInteractionClient extends BaseInteractionClient {
constructor(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, provider, accountId, nativeStorageImpl, correlationId) {
super(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, performanceClient, correlationId, provider);
this.apiId = apiId;
this.accountId = accountId;
this.platformAuthProvider = provider;
this.nativeStorageManager = nativeStorageImpl;
this.silentCacheClient = new SilentCacheClient(config, this.nativeStorageManager, browserCrypto, logger, eventHandler, navigationClient, performanceClient, correlationId, provider);
const extensionName = this.platformAuthProvider.getExtensionName();
this.skus = ServerTelemetryManager.makeExtraSkuString({
libraryName: BrowserConstants.MSAL_SKU,
libraryVersion: version,
extensionName: extensionName,
extensionVersion: this.platformAuthProvider.getExtensionVersion(),
});
}
/**
* Adds SKUs to request extra query parameters
* @param request {PlatformAuthRequest}
* @private
*/
addRequestSKUs(request) {
request.extraParameters = {
...request.extraParameters,
[AADServerParamKeys.X_CLIENT_EXTRA_SKU]: this.skus,
};
}
/**
* Acquire token from native platform via browser extension
* @param request
*/
async acquireToken(request, cacheLookupPolicy) {
this.logger.trace("03qeos", this.correlationId);
// start the perf measurement
const nativeATMeasurement = this.performanceClient.startMeasurement(NativeInteractionClientAcquireToken, this.correlationId);
const reqTimestamp = TimeUtils.nowSeconds();
const serverTelemetryManager = initializeServerTelemetryManager(this.apiId, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
try {
// initialize native request
const nativeRequest = await this.initializePlatformRequest(request);
// check if the tokens can be retrieved from internal cache
try {
const result = await this.acquireTokensFromCache(this.accountId, nativeRequest);
nativeATMeasurement.end({
success: true,
isNativeBroker: false,
fromCache: true,
});
return result;
}
catch (e) {
if (cacheLookupPolicy === CacheLookupPolicy.AccessToken) {
this.logger.info("0eitbc", this.correlationId);
nativeATMeasurement.end({
success: false,
brokerErrorCode: "cache_request_failed",
});
throw e;
}
// continue with a native call for any and all errors
this.logger.info("0957j1", this.correlationId);
}
const validatedResponse = await this.platformAuthProvider.sendMessage(nativeRequest);
return await this.handleNativeResponse(validatedResponse, nativeRequest, reqTimestamp)
.then((result) => {
nativeATMeasurement.end({
success: true,
isNativeBroker: true,
requestId: result.requestId,
});
serverTelemetryManager.clearNativeBrokerErrorCode();
return result;
})
.catch((error) => {
nativeATMeasurement.end({
success: false,
errorCode: error.errorCode,
subErrorCode: error.subError,
});
throw error;
});
}
catch (e) {
if (e instanceof NativeAuthError) {
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
}
nativeATMeasurement.end({
success: false,
});
throw e;
}
}
/**
* Creates silent flow request
* @param request
* @param cachedAccount
* @returns CommonSilentFlowRequest
*/
createSilentCacheRequest(request, cachedAccount) {
return {
authority: request.authority,
correlationId: this.correlationId,
scopes: ScopeSet.fromString(request.scope).asArray(),
account: cachedAccount,
forceRefresh: false,
};
}
/**
* Fetches the tokens from the cache if un-expired
* @param nativeAccountId
* @param request
* @returns authenticationResult
*/
async acquireTokensFromCache(nativeAccountId, request) {
if (!nativeAccountId) {
this.logger.warning("1ndf3e", this.correlationId);
throw createClientAuthError(ClientAuthErrorCodes.noAccountFound);
}
// fetch the account from browser cache
const account = this.browserStorage.getBaseAccountInfo({
nativeAccountId,
}, this.correlationId);
if (!account) {
throw createClientAuthError(ClientAuthErrorCodes.noAccountFound);
}
// leverage silent flow for cached tokens retrieval
try {
const silentRequest = this.createSilentCacheRequest(request, account);
const result = await this.silentCacheClient.acquireToken(silentRequest);
const idToken = this.browserStorage.getIdToken(account, this.correlationId, this.browserStorage.getTokenKeys(), account.tenantId);
const idTokenClaims = AuthToken.extractTokenClaims(idToken?.secret || "", base64Decode);
const fullAccount = updateAccountTenantProfileData(account, undefined, // tenantProfile optional
idTokenClaims, idToken?.secret);
return {
...result,
idToken: idToken?.secret || "",
idTokenClaims: idTokenClaims,
account: fullAccount,
};
}
catch (e) {
throw e;
}
}
/**
* Acquires a token from native platform then redirects to the redirectUri instead of returning the response
* @param {RedirectRequest} request
* @param {InProgressPerformanceEvent} rootMeasurement
* @param {HandleRedirectPromiseOptions} options
*/
async acquireTokenRedirect(request, rootMeasurement, options) {
this.logger.trace("0luikq", this.correlationId);
const nativeRequest = await this.initializePlatformRequest(request);
const navigateToLoginRequestUrl = options?.navigateToLoginRequestUrl ?? true;
try {
await this.platformAuthProvider.sendMessage(nativeRequest);
}
catch (e) {
// Only throw fatal errors here to allow application to fallback to regular redirect. Otherwise proceed and the error will be thrown in handleRedirectPromise
if (e instanceof NativeAuthError) {
const serverTelemetryManager = initializeServerTelemetryManager(this.apiId, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
if (isFatalNativeAuthError(e)) {
throw e;
}
}
}
this.browserStorage.setTemporaryCache(TemporaryCacheKeys.NATIVE_REQUEST, JSON.stringify(nativeRequest), true);
const navigationOptions = {
apiId: ApiId.acquireTokenRedirect,
timeout: this.config.system.redirectNavigationTimeout,
noHistory: false,
};
const redirectUri = navigateToLoginRequestUrl
? window.location.href
: getRedirectUri(request.redirectUri, this.config.auth.redirectUri, this.logger, this.correlationId);
rootMeasurement.end({ success: true });
await this.navigationClient.navigateExternal(redirectUri, navigationOptions); // Need to treat this as external to ensure handleRedirectPromise is run again
}
/**
* If the previous page called native platform for a token using redirect APIs, send the same request again and return the response
* @param performanceClient {IPerformanceClient?}
* @param correlationId {string?} correlation identifier
*/
async handleRedirectPromise() {
this.logger.trace("1c5lhw", this.correlationId);
if (!this.browserStorage.isInteractionInProgress(true)) {
this.logger.info("0le6uv", this.correlationId);
return null;
}
// remove prompt from the request to prevent WAM from prompting twice
const cachedRequest = this.browserStorage.getCachedNativeRequest();
if (!cachedRequest) {
this.logger.verbose("0a6zjb", this.correlationId);
this.performanceClient?.addFields({ errorCode: "no_cached_request" }, this.correlationId);
return null;
}
const { prompt, ...request } = cachedRequest;
if (prompt) {
this.logger.verbose("0ac34v", this.correlationId);
}
this.browserStorage.removeItem(this.browserStorage.generateCacheKey(TemporaryCacheKeys.NATIVE_REQUEST));
const reqTimestamp = TimeUtils.nowSeconds();
try {
this.logger.verbose("003x5a", this.correlationId);
const response = await this.platformAuthProvider.sendMessage(request);
const authResult = await this.handleNativeResponse(response, request, reqTimestamp);
const serverTelemetryManager = initializeServerTelemetryManager(this.apiId, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
serverTelemetryManager.clearNativeBrokerErrorCode();
this.performanceClient?.addFields({ isNativeBroker: true }, this.correlationId);
return authResult;
}
catch (e) {
throw e;
}
}
/**
* Logout from native platform via browser extension
* @param request
*/
logout() {
this.logger.trace("0u2sjm", this.correlationId);
return Promise.reject("Logout not implemented yet");
}
/**
* Transform response from native platform into AuthenticationResult object which will be returned to the end user
* @param response
* @param request
* @param reqTimestamp
*/
async handleNativeResponse(response, request, reqTimestamp) {
this.logger.trace("1bojln", this.correlationId);
// generate identifiers
const idTokenClaims = AuthToken.extractTokenClaims(response.id_token, base64Decode);
const homeAccountIdentifier = this.createHomeAccountIdentifier(response, idTokenClaims);
const cachedhomeAccountId = this.browserStorage.getAccountInfoFilteredBy({
nativeAccountId: request.accountId,
}, this.correlationId)?.homeAccountId;
// add exception for double brokering, please note this is temporary and will be fortified in future
if (request.extraParameters?.child_client_id &&
response.account.id !== request.accountId) {
this.logger.info("1ub1in", this.correlationId);
}
else if (homeAccountIdentifier !== cachedhomeAccountId &&
response.account.id !== request.accountId) {
// User switch in native broker prompt is not supported. All users must first sign in through web flow to ensure server state is in sync
throw createNativeAuthError(userSwitch);
}
// Get the preferred_cache domain for the given authority
const authority = await getDiscoveredAuthority(this.config, this.correlationId, this.performanceClient, this.browserStorage, this.logger, request.authority);
const baseAccount = buildAccountToCache(this.browserStorage, authority, homeAccountIdentifier, base64Decode, this.correlationId, idTokenClaims, response.client_info, authority.getPreferredCache(), // environment
idTokenClaims.tid, undefined, // auth code payload
response.account.id, this.logger, this.performanceClient);
// Ensure expires_in is in number format
response.expires_in = Number(response.expires_in);
// generate authenticationResult
const result = await this.generateAuthenticationResult(response, request, idTokenClaims, baseAccount, authority.canonicalAuthority, reqTimestamp);
// cache accounts and tokens in the appropriate storage
await this.cacheAccount(baseAccount, AuthToken.isKmsi(idTokenClaims));
await this.cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, result.tenantId, reqTimestamp, authority.getPreferredCache() // environment
);
return result;
}
/**
* creates an homeAccountIdentifier for the account
* @param response
* @param idTokenObj
* @returns
*/
createHomeAccountIdentifier(response, idTokenClaims) {
// Save account in browser storage
const homeAccountIdentifier = AccountEntityUtils.generateHomeAccountId(response.client_info || "", AuthorityType.Default, this.logger, this.browserCrypto, this.correlationId, idTokenClaims);
return homeAccountIdentifier;
}
/**
* Helper to generate scopes
* @param response
* @param request
* @returns
*/
generateScopes(requestScopes, responseScopes) {
return responseScopes
? ScopeSet.fromString(responseScopes)
: ScopeSet.fromString(requestScopes);
}
/**
* If PoP token is requesred, records the PoP token if returned from the WAM, else generates one in the browser
* @param request
* @param response
*/
async generatePopAccessToken(response, request) {
if (request.tokenType === Constants.AuthenticationScheme.POP &&
request.signPopToken) {
/**
* This code prioritizes SHR returned from the native layer. In case of error/SHR not calculated from WAM and the AT
* is still received, SHR is calculated locally
*/
// Check if native layer returned an SHR token
if (response.shr) {
this.logger.trace("0coqhu", this.correlationId);
return response.shr;
}
// Generate SHR in msal js if WAM does not compute it when POP is enabled
const popTokenGenerator = new PopTokenGenerator(this.browserCrypto, this.performanceClient);
const shrParameters = {
resourceRequestMethod: request.resourceRequestMethod,
resourceRequestUri: request.resourceRequestUri,
shrClaims: request.shrClaims,
shrNonce: request.shrNonce,
correlationId: this.correlationId,
};
/**
* KeyID must be present in the native request from when the PoP key was generated in order for
* PopTokenGenerator to query the full key for signing
*/
if (!request.keyId) {
throw createClientAuthError(ClientAuthErrorCodes.keyIdMissing);
}
return popTokenGenerator.signPopToken(response.access_token, request.keyId, shrParameters);
}
else {
return response.access_token;
}
}
/**
* Generates authentication result
* @param response
* @param request
* @param idTokenObj
* @param accountEntity
* @param authority
* @param reqTimestamp
* @returns
*/
async generateAuthenticationResult(response, request, idTokenClaims, accountEntity, authority, reqTimestamp) {
// Add Native Broker fields to Telemetry
const mats = this.addTelemetryFromNativeResponse(response.properties.MATS);
// If scopes not returned in server response, use request scopes
const responseScopes = this.generateScopes(request.scope, response.scope);
const accountProperties = response.account.properties || {};
const uid = accountProperties["UID"] ||
idTokenClaims.oid ||
idTokenClaims.sub ||
"";
const tid = accountProperties["TenantId"] || idTokenClaims.tid || "";
const accountInfo = updateAccountTenantProfileData(AccountEntityUtils.getAccountInfo(accountEntity), undefined, // tenantProfile optional
idTokenClaims, response.id_token);
/**
* In pairwise broker flows, this check prevents the broker's native account id
* from being returned over the embedded app's account id.
*/
if (accountInfo.nativeAccountId !== response.account.id) {
accountInfo.nativeAccountId = response.account.id;
}
// generate PoP token as needed
const responseAccessToken = await this.generatePopAccessToken(response, request);
const tokenType = request.tokenType === Constants.AuthenticationScheme.POP
? Constants.AuthenticationScheme.POP
: Constants.AuthenticationScheme.BEARER;
const result = {
authority: authority,
uniqueId: uid,
tenantId: tid,
scopes: responseScopes.asArray(),
account: accountInfo,
idToken: response.id_token,
idTokenClaims: idTokenClaims,
accessToken: responseAccessToken,
fromCache: mats ? this.isResponseFromCache(mats) : false,
// Request timestamp and NativeResponse expires_in are in seconds, converting to Date for AuthenticationResult
expiresOn: TimeUtils.toDateFromSeconds(reqTimestamp + response.expires_in),
tokenType: tokenType,
correlationId: this.correlationId,
state: response.state,
fromPlatformBroker: true,
...(request.resource && { resource: request.resource }),
};
return result;
}
/**
* cache the account entity in browser storage
* @param accountEntity
*/
async cacheAccount(accountEntity, kmsi) {
// Store the account info and hence `nativeAccountId` in browser cache
await this.browserStorage.setAccount(accountEntity, this.correlationId, kmsi, this.apiId);
// Remove any existing cached tokens for this account in browser storage
this.browserStorage.removeAccountContext(AccountEntityUtils.getAccountInfo(accountEntity), this.correlationId);
}
/**
* Stores the access_token and id_token in inmemory storage
* @param response
* @param request
* @param homeAccountIdentifier
* @param idTokenObj
* @param responseAccessToken
* @param tenantId
* @param reqTimestamp
*/
async cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, tenantId, reqTimestamp, environment) {
const cachedIdToken = CacheHelpers.createIdTokenEntity(homeAccountIdentifier, environment, response.id_token || "", request.clientId, idTokenClaims.tid || "");
// cache accessToken in inmemory storage
const expiresIn = request.tokenType === Constants.AuthenticationScheme.POP
? Constants.SHR_NONCE_VALIDITY
: (typeof response.expires_in === "string"
? parseInt(response.expires_in, 10)
: response.expires_in) || 0;
const tokenExpirationSeconds = reqTimestamp + expiresIn;
const responseScopes = this.generateScopes(response.scope, request.scope);
const cachedAccessToken = CacheHelpers.createAccessTokenEntity(homeAccountIdentifier, environment, response.access_token, request.clientId, idTokenClaims.tid || tenantId, responseScopes.printScopes(), tokenExpirationSeconds, 0, base64Decode, undefined, request.tokenType, undefined, request.keyId);
// save idtoken credential in configured browser storage
if (!!cachedIdToken && request.storeInCache?.idToken !== false) {
await this.browserStorage.setIdTokenCredential(cachedIdToken, this.correlationId, AuthToken.isKmsi(idTokenClaims));
}
// save access token credential in memory storage
const nativeCacheRecord = {
accessToken: cachedAccessToken,
};
return this.nativeStorageManager.saveCacheRecord(nativeCacheRecord, this.correlationId, AuthToken.isKmsi(idTokenClaims), this.apiId, request.storeInCache);
}
getExpiresInValue(tokenType, expiresIn) {
return tokenType === Constants.AuthenticationScheme.POP
? Constants.SHR_NONCE_VALIDITY
: (typeof expiresIn === "string"
? parseInt(expiresIn, 10)
: expiresIn) || 0;
}
addTelemetryFromNativeResponse(matsResponse) {
const mats = this.getMATSFromResponse(matsResponse);
if (!mats) {
return null;
}
this.performanceClient.addFields({
extensionId: this.platformAuthProvider.getExtensionId(),
extensionVersion: this.platformAuthProvider.getExtensionVersion(),
matsBrokerVersion: mats.broker_version,
matsAccountJoinOnStart: mats.account_join_on_start,
matsAccountJoinOnEnd: mats.account_join_on_end,
matsDeviceJoin: mats.device_join,
matsPromptBehavior: mats.prompt_behavior,
matsApiErrorCode: mats.api_error_code,
matsUiVisible: mats.ui_visible,
matsSilentCode: mats.silent_code,
matsSilentBiSubCode: mats.silent_bi_sub_code,
matsSilentMessage: mats.silent_message,
matsSilentStatus: mats.silent_status,
matsHttpStatus: mats.http_status,
matsHttpEventCount: mats.http_event_count,
}, this.correlationId);
return mats;
}
/**
* Gets MATS telemetry from native response
* @param response
* @returns
*/
getMATSFromResponse(matsResponse) {
if (matsResponse) {
try {
return JSON.parse(matsResponse);
}
catch (e) {
this.logger.error("0b3l57", this.correlationId);
}
}
return null;
}
/**
* Returns whether or not response came from native cache
* @param response
* @returns
*/
isResponseFromCache(mats) {
if (typeof mats.is_cached === "undefined") {
this.logger.verbose("1okqev", this.correlationId);
return false;
}
return !!mats.is_cached;
}
/**
* Translates developer provided request object into NativeRequest object
* @param request
*/
async initializePlatformRequest(request) {
this.logger.trace("1xdm2a", this.correlationId);
const canonicalAuthority = await this.getCanonicalAuthority(request);
// ignore config claims if skipBrokerClaims is set to true and this is a brokered authentication flow
const configClaims = request.skipBrokerClaims && !!request.embeddedClientId
? undefined
: this.config.auth.clientCapabilities;
// scopes are expected to be received by the native broker as "scope" and will be added to the request below. Other properties that should be dropped from the request to the native broker can be included in the object destructuring here.
const { scopes, claims, ...remainingProperties } = request;
const scopeSet = new ScopeSet(scopes || []);
scopeSet.appendScopes(Constants.OIDC_DEFAULT_SCOPES);
const mergedClaims = configClaims && configClaims.length
? RequestParameterBuilder.addClientCapabilitiesToClaims(claims, configClaims)
: claims;
const validatedRequest = {
...remainingProperties,
claims: mergedClaims,
accountId: this.accountId,
clientId: this.config.auth.clientId,
authority: canonicalAuthority.urlString,
scope: scopeSet.printScopes(),
redirectUri: getRedirectUri(request.redirectUri, this.config.auth.redirectUri, this.logger, this.correlationId),
prompt: this.getPrompt(request.prompt),
correlationId: this.correlationId,
tokenType: request.authenticationScheme,
windowTitleSubstring: document.title,
extraParameters: {
...request.extraParameters,
},
extendedExpiryToken: false,
keyId: request.popKid,
};
// Check for PoP token requests: signPopToken should only be set to true if popKid is not set
if (validatedRequest.signPopToken && !!request.popKid) {
throw createBrowserAuthError(invalidPopTokenRequest);
}
this.handleExtraBrokerParams(validatedRequest);
validatedRequest.extraParameters =
validatedRequest.extraParameters || {};
validatedRequest.extraParameters.telemetry =
PlatformAuthConstants.MATS_TELEMETRY;
if (request.authenticationScheme === Constants.AuthenticationScheme.POP) {
// add POP request type
const shrParameters = {
resourceRequestUri: request.resourceRequestUri,
resourceRequestMethod: request.resourceRequestMethod,
shrClaims: request.shrClaims,
shrNonce: request.shrNonce,
correlationId: this.correlationId,
};
const popTokenGenerator = new PopTokenGenerator(this.browserCrypto, this.performanceClient);
// generate reqCnf if not provided in the request
let reqCnfData;
if (!validatedRequest.keyId) {
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, this.logger, this.performanceClient, this.correlationId)(shrParameters, this.logger);
reqCnfData = generatedReqCnfData.reqCnfString;
validatedRequest.keyId = generatedReqCnfData.kid;
validatedRequest.signPopToken = true;
}
else {
reqCnfData = this.browserCrypto.base64UrlEncode(JSON.stringify({ kid: validatedRequest.keyId }));
validatedRequest.signPopToken = false;
}
// SPAs require whole string to be passed to broker
validatedRequest.reqCnf = reqCnfData;
}
this.addRequestSKUs(validatedRequest);
return validatedRequest;
}
async getCanonicalAuthority(request) {
const requestAuthority = request.authority || this.config.auth.authority;
const { azureCloudOptions, account } = request;
if (account) {
// validate authority
await getDiscoveredAuthority(this.config, this.correlationId, this.performanceClient, this.browserStorage, this.logger, requestAuthority, azureCloudOptions, undefined, // requestExtraQueryParameters
account);
}
const canonicalAuthority = new UrlString(requestAuthority);
canonicalAuthority.validateAsUri();
return canonicalAuthority;
}
getPrompt(prompt) {
// If request is silent, prompt is always none
switch (this.apiId) {
case ApiId.ssoSilent:
case ApiId.acquireTokenSilent_silentFlow:
this.logger.trace("12n1y2", this.correlationId);
return Constants.PromptValue.NONE;
}
// Prompt not provided, request may proceed and native broker decides if it needs to prompt
if (!prompt) {
this.logger.trace("0uid1p", this.correlationId);
return undefined;
}
// If request is interactive, check if prompt provided is allowed to go directly to native broker
switch (prompt) {
case Constants.PromptValue.NONE:
case Constants.PromptValue.CONSENT:
case Constants.PromptValue.LOGIN:
this.logger.trace("0i0hco", this.correlationId);
return prompt;
default:
this.logger.trace("0w3tpw", this.correlationId);
throw createBrowserAuthError(nativePromptNotSupported);
}
}
/**
* Handles extra broker request parameters
* @param request {PlatformAuthRequest}
* @private
*/
handleExtraBrokerParams(request) {
const hasExtraBrokerParams = request.extraParameters &&
request.extraParameters.hasOwnProperty(AADServerParamKeys.BROKER_CLIENT_ID) &&
request.extraParameters.hasOwnProperty(AADServerParamKeys.BROKER_REDIRECT_URI) &&
request.extraParameters.hasOwnProperty(AADServerParamKeys.CLIENT_ID);
if (!request.embeddedClientId && !hasExtraBrokerParams) {
return;
}
let child_client_id = "";
const child_redirect_uri = request.redirectUri;
if (request.embeddedClientId) {
request.redirectUri = this.config.auth.redirectUri;
child_client_id = request.embeddedClientId;
}
else if (request.extraParameters) {
request.redirectUri =
request.extraParameters[AADServerParamKeys.BROKER_REDIRECT_URI];
child_client_id =
request.extraParameters[AADServerParamKeys.CLIENT_ID];
}
request.extraParameters = {
child_client_id,
child_redirect_uri,
};
this.performanceClient?.addFields({
embeddedClientId: child_client_id,
embeddedRedirectUri: child_redirect_uri,
}, this.correlationId);
}
}
export { PlatformAuthInteractionClient };
//# sourceMappingURL=PlatformAuthInteractionClient.mjs.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,438 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { Constants, invokeAsync, ProtocolMode, PerformanceEvents, invoke, AuthError, UrlString, ProtocolUtils } from '@azure/msal-common/browser';
import { StandardInteractionClient, initializeAuthorizationRequest } from './StandardInteractionClient.mjs';
import { StandardInteractionClientInitializeAuthorizationRequest, GeneratePkceCodes, StandardInteractionClientCreateAuthCodeClient, DeserializeResponse, HandleResponseCode, StandardInteractionClientGetDiscoveredAuthority, GenerateEarKey, SilentHandlerMonitorIframeForHash, HandleResponseEar } from '../telemetry/BrowserPerformanceEvents.mjs';
import { EventType } from '../event/EventType.mjs';
import { InteractionType, ApiId, BrowserConstants } from '../utils/BrowserConstants.mjs';
import { preconnect, waitForBridgeResponse, getCurrentUri } from '../utils/BrowserUtils.mjs';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { deserializeResponse } from '../response/ResponseHandler.mjs';
import { getAuthCodeRequestUrl, handleResponseCode, getEARForm, handleResponseEAR, getCodeForm } from '../protocol/Authorize.mjs';
import { generatePkceCodes } from '../crypto/PkceGenerator.mjs';
import { isPlatformAuthAllowed } from '../broker/nativeBroker/PlatformAuthProvider.mjs';
import { generateEarKey } from '../crypto/BrowserCrypto.mjs';
import { initializeServerTelemetryManager, getDiscoveredAuthority, clearCacheOnLogout } from './BaseInteractionClient.mjs';
import { validateRequestMethod } from '../request/RequestHelpers.mjs';
import { emptyNavigateUri, emptyWindowError, popupWindowError } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class PopupClient extends StandardInteractionClient {
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl, correlationId, platformAuthHandler) {
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, correlationId, platformAuthHandler);
this.nativeStorage = nativeStorageImpl;
this.eventHandler = eventHandler;
}
/**
* Acquires tokens by opening a popup window to the /authorize endpoint of the authority
* @param request
* @param pkceCodes
*/
acquireToken(request, pkceCodes) {
let popupParams = undefined;
try {
const popupName = this.generatePopupName(request.scopes || Constants.OIDC_DEFAULT_SCOPES, request.authority || this.config.auth.authority);
popupParams = {
popupName,
popupWindowAttributes: request.popupWindowAttributes || {},
popupWindowParent: request.popupWindowParent ?? window,
};
this.performanceClient.addFields({ isAsyncPopup: !this.config.system.navigatePopups }, this.correlationId);
// navigatePopups flag is false. Acquires token without first opening popup. Popup will be opened later asynchronously.
if (!this.config.system.navigatePopups) {
this.logger.verbose("162h4u", this.correlationId);
// Passes on popup position and dimensions if in request
return this.acquireTokenPopupAsync(request, popupParams, pkceCodes);
}
else {
// navigatePopups flag is set to true. Opens popup before acquiring token.
// Pre-validate request method to avoid opening popup if the request is invalid
const validatedRequest = {
...request,
httpMethod: validateRequestMethod(request, this.config.system.protocolMode),
};
this.logger.verbose("1f9ok3", this.correlationId);
popupParams.popup = this.openSizedPopup("about:blank", popupParams);
return this.acquireTokenPopupAsync(validatedRequest, popupParams, pkceCodes);
}
}
catch (e) {
return Promise.reject(e);
}
}
/**
* Clears local cache for the current user then opens a popup window prompting the user to sign-out of the server
* @param logoutRequest
*/
logout(logoutRequest) {
try {
this.logger.verbose("068rup", this.correlationId);
const validLogoutRequest = this.initializeLogoutRequest(logoutRequest);
const popupParams = {
popupName: this.generateLogoutPopupName(validLogoutRequest),
popupWindowAttributes: logoutRequest?.popupWindowAttributes || {},
popupWindowParent: logoutRequest?.popupWindowParent ?? window,
};
const authority = logoutRequest && logoutRequest.authority;
const mainWindowRedirectUri = logoutRequest && logoutRequest.mainWindowRedirectUri;
// navigatePopups flag set to false. Acquires token without first opening popup. Popup will be opened later asynchronously.
if (!this.config.system.navigatePopups) {
this.logger.verbose("1phd8u", this.correlationId);
// Passes on popup position and dimensions if in request
return this.logoutPopupAsync(validLogoutRequest, popupParams, authority, mainWindowRedirectUri);
}
else {
// navigatePopups flag is set to true. Opens popup before logging out.
this.logger.verbose("1a28da", this.correlationId);
popupParams.popup = this.openSizedPopup("about:blank", popupParams);
return this.logoutPopupAsync(validLogoutRequest, popupParams, authority, mainWindowRedirectUri);
}
}
catch (e) {
// Since this function is synchronous we need to reject
return Promise.reject(e);
}
}
/**
* Helper which obtains an access_token for your API via opening a popup window in the user's browser
* @param request
* @param popupParams
* @param pkceCodes
*
* @returns A promise that is fulfilled when this function has completed, or rejected if an error was raised.
*/
async acquireTokenPopupAsync(request, popupParams, pkceCodes) {
this.logger.verbose("1g77pg", this.correlationId);
const validRequest = await invokeAsync(initializeAuthorizationRequest, StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(request, InteractionType.Popup, this.config, this.browserCrypto, this.browserStorage, this.logger, this.performanceClient, this.correlationId);
/*
* Skip pre-connect for async popups to reduce time between user interaction and popup window creation to avoid
* popup from being blocked by browsers with shorter popup timers
*/
if (popupParams.popup) {
preconnect(validRequest.authority);
}
const isPlatformBroker = isPlatformAuthAllowed(this.config, this.logger, this.correlationId, this.platformAuthProvider, request.authenticationScheme);
validRequest.platformBroker = isPlatformBroker;
if (this.config.system.protocolMode === ProtocolMode.EAR) {
return this.executeEarFlow(validRequest, popupParams, pkceCodes);
}
else {
return this.executeCodeFlow(validRequest, popupParams, pkceCodes);
}
}
/**
* Executes auth code + PKCE flow
* @param request
* @param popupParams
* @param pkceCodes
* @returns
*/
async executeCodeFlow(request, popupParams, pkceCodes) {
const correlationId = request.correlationId;
const serverTelemetryManager = initializeServerTelemetryManager(ApiId.acquireTokenPopup, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
const pkce = pkceCodes ||
(await invokeAsync(generatePkceCodes, GeneratePkceCodes, this.logger, this.performanceClient, correlationId)(this.performanceClient, this.logger, correlationId));
const popupRequest = {
...request,
codeChallenge: pkce.challenge,
};
try {
// Initialize the client
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, correlationId)({
serverTelemetryManager,
requestAuthority: popupRequest.authority,
requestAzureCloudOptions: popupRequest.azureCloudOptions,
requestExtraQueryParameters: popupRequest.extraQueryParameters,
account: popupRequest.account,
});
if (popupRequest.httpMethod === Constants.HttpMethod.POST) {
return await this.executeCodeFlowWithPost(popupRequest, popupParams, authClient, pkce.verifier);
}
else {
// Create acquire token url.
const navigateUrl = await invokeAsync(getAuthCodeRequestUrl, PerformanceEvents.GetAuthCodeUrl, this.logger, this.performanceClient, correlationId)(this.config, authClient.authority, popupRequest, this.logger, this.performanceClient);
// Show the UI once the url has been created. Get the window handle for the popup.
const popupWindow = this.initiateAuthRequest(navigateUrl, popupParams);
this.eventHandler.emitEvent(EventType.POPUP_OPENED, correlationId, InteractionType.Popup, { popupWindow }, null);
// Wait for the redirect bridge response
const responseString = await waitForBridgeResponse(this.config.system.popupBridgeTimeout, this.logger, this.browserCrypto, request, this.performanceClient);
const serverParams = invoke(deserializeResponse, DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.responseMode, this.logger, this.correlationId);
return await invokeAsync(handleResponseCode, HandleResponseCode, this.logger, this.performanceClient, correlationId)(request, serverParams, pkce.verifier, ApiId.acquireTokenPopup, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
}
}
catch (e) {
// Close the synchronous popup if an error is thrown before the window unload event is registered
popupParams.popup?.close();
if (e instanceof AuthError) {
e.setCorrelationId(this.correlationId);
serverTelemetryManager.cacheFailedRequest(e);
}
throw e;
}
}
/**
* Executes EAR flow
* @param request
*/
async executeEarFlow(request, popupParams, pkceCodes) {
const { correlationId, authority, azureCloudOptions, extraQueryParameters, account, } = request;
// Get the frame handle for the silent request
const discoveredAuthority = await invokeAsync(getDiscoveredAuthority, StandardInteractionClientGetDiscoveredAuthority, this.logger, this.performanceClient, correlationId)(this.config, this.correlationId, this.performanceClient, this.browserStorage, this.logger, authority, azureCloudOptions, extraQueryParameters, account);
const earJwk = await invokeAsync(generateEarKey, GenerateEarKey, this.logger, this.performanceClient, correlationId)();
const pkce = pkceCodes ||
(await invokeAsync(generatePkceCodes, GeneratePkceCodes, this.logger, this.performanceClient, correlationId)(this.performanceClient, this.logger, correlationId));
const popupRequest = {
...request,
earJwk: earJwk,
codeChallenge: pkce.challenge,
};
const popupWindow = popupParams.popup || this.openPopup("about:blank", popupParams);
const form = await getEARForm(popupWindow.document, this.config, discoveredAuthority, popupRequest, this.logger, this.performanceClient);
form.submit();
// Monitor the popup for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
const responseString = await invokeAsync(waitForBridgeResponse, SilentHandlerMonitorIframeForHash, this.logger, this.performanceClient, correlationId)(this.config.system.popupBridgeTimeout, this.logger, this.browserCrypto, popupRequest, this.performanceClient);
const serverParams = invoke(deserializeResponse, DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.responseMode, this.logger, this.correlationId);
if (!serverParams.ear_jwe && serverParams.code) {
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, correlationId)({
serverTelemetryManager: initializeServerTelemetryManager(ApiId.acquireTokenPopup, this.config.auth.clientId, correlationId, this.browserStorage, this.logger),
requestAuthority: request.authority,
requestAzureCloudOptions: request.azureCloudOptions,
requestExtraQueryParameters: request.extraQueryParameters,
account: request.account,
authority: discoveredAuthority,
});
return invokeAsync(handleResponseCode, HandleResponseCode, this.logger, this.performanceClient, correlationId)(popupRequest, serverParams, pkce.verifier, ApiId.acquireTokenPopup, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
}
else {
return invokeAsync(handleResponseEAR, HandleResponseEar, this.logger, this.performanceClient, correlationId)(popupRequest, serverParams, ApiId.acquireTokenPopup, this.config, discoveredAuthority, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
}
}
async executeCodeFlowWithPost(request, popupParams, authClient, pkceVerifier) {
const correlationId = request.correlationId;
// Get the frame handle for the silent request
const discoveredAuthority = await invokeAsync(getDiscoveredAuthority, StandardInteractionClientGetDiscoveredAuthority, this.logger, this.performanceClient, correlationId)(this.config, this.correlationId, this.performanceClient, this.browserStorage, this.logger);
const popupWindow = popupParams.popup || this.openPopup("about:blank", popupParams);
const form = await getCodeForm(popupWindow.document, this.config, discoveredAuthority, request, this.logger, this.performanceClient);
form.submit();
// Monitor the popup for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
const responseString = await invokeAsync(waitForBridgeResponse, SilentHandlerMonitorIframeForHash, this.logger, this.performanceClient, correlationId)(this.config.system.popupBridgeTimeout, this.logger, this.browserCrypto, request, this.performanceClient);
const serverParams = invoke(deserializeResponse, DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.responseMode, this.logger, this.correlationId);
return invokeAsync(handleResponseCode, HandleResponseCode, this.logger, this.performanceClient, correlationId)(request, serverParams, pkceVerifier, ApiId.acquireTokenPopup, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
}
/**
*
* @param validRequest
* @param popupName
* @param requestAuthority
* @param popup
* @param mainWindowRedirectUri
* @param popupWindowAttributes
*/
async logoutPopupAsync(validRequest, popupParams, requestAuthority, mainWindowRedirectUri) {
this.logger.verbose("0b7yrk", this.correlationId);
this.eventHandler.emitEvent(EventType.LOGOUT_START, this.correlationId, InteractionType.Popup, validRequest);
const serverTelemetryManager = initializeServerTelemetryManager(ApiId.logoutPopup, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
try {
// Clear cache on logout
await clearCacheOnLogout(this.browserStorage, this.browserCrypto, this.logger, this.correlationId, validRequest.account);
// Initialize the client
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)({
serverTelemetryManager,
requestAuthority: requestAuthority,
account: validRequest.account || undefined,
});
try {
authClient.authority.endSessionEndpoint;
}
catch {
if (validRequest.account?.homeAccountId &&
validRequest.postLogoutRedirectUri &&
authClient.authority.protocolMode === ProtocolMode.OIDC) {
this.eventHandler.emitEvent(EventType.LOGOUT_SUCCESS, validRequest.correlationId, InteractionType.Popup, validRequest);
if (mainWindowRedirectUri) {
const navigationOptions = {
apiId: ApiId.logoutPopup,
timeout: this.config.system.redirectNavigationTimeout,
noHistory: false,
};
const absoluteUrl = UrlString.getAbsoluteUrl(mainWindowRedirectUri, getCurrentUri());
await this.navigationClient.navigateInternal(absoluteUrl, navigationOptions);
}
popupParams.popup?.close();
return;
}
}
// Redirect bridge requires "state" param to work properly
validRequest.state = ProtocolUtils.setRequestState(this.browserCrypto, validRequest.state || "", {
interactionType: InteractionType.Popup,
});
// Create logout string and navigate user window to logout.
const logoutUri = authClient.getLogoutUri(validRequest);
this.eventHandler.emitEvent(EventType.LOGOUT_SUCCESS, validRequest.correlationId, InteractionType.Popup, validRequest);
// Open the popup window to requestUrl.
const popupWindow = this.openPopup(logoutUri, popupParams);
this.eventHandler.emitEvent(EventType.POPUP_OPENED, validRequest.correlationId, InteractionType.Popup, { popupWindow }, null);
await waitForBridgeResponse(this.config.system.popupBridgeTimeout, this.logger, this.browserCrypto, validRequest, this.performanceClient).catch(() => {
// Swallow any errors related to monitoring the window. Server logout is best effort
});
if (mainWindowRedirectUri) {
const navigationOptions = {
apiId: ApiId.logoutPopup,
timeout: this.config.system.redirectNavigationTimeout,
noHistory: false,
};
const absoluteUrl = UrlString.getAbsoluteUrl(mainWindowRedirectUri, getCurrentUri());
this.logger.verbose("0qcur2", this.correlationId);
this.logger.verbosePii("0oj7lk", this.correlationId);
await this.navigationClient.navigateInternal(absoluteUrl, navigationOptions);
}
else {
this.logger.verbose("03zgcf", this.correlationId);
}
}
catch (e) {
// Close the synchronous popup if an error is thrown before the window unload event is registered
popupParams.popup?.close();
if (e instanceof AuthError) {
e.setCorrelationId(this.correlationId);
serverTelemetryManager.cacheFailedRequest(e);
}
this.eventHandler.emitEvent(EventType.LOGOUT_FAILURE, this.correlationId, InteractionType.Popup, null, e);
this.eventHandler.emitEvent(EventType.LOGOUT_END, this.correlationId, InteractionType.Popup);
throw e;
}
this.eventHandler.emitEvent(EventType.LOGOUT_END, this.correlationId, InteractionType.Popup);
}
/**
* Opens a popup window with given request Url.
* @param requestUrl
*/
initiateAuthRequest(requestUrl, params) {
// Check that request url is not empty.
if (requestUrl) {
this.logger.infoPii("1kcr9k", this.correlationId);
// Open the popup window to requestUrl.
return this.openPopup(requestUrl, params);
}
else {
// Throw error if request URL is empty.
this.logger.error("1l7hyp", this.correlationId);
throw createBrowserAuthError(emptyNavigateUri);
}
}
/**
* @hidden
*
* Configures popup window for login.
*
* @param urlNavigate
* @param title
* @param popUpWidth
* @param popUpHeight
* @param popupWindowAttributes
* @ignore
* @hidden
*/
openPopup(urlNavigate, popupParams) {
try {
let popupWindow;
// Popup window passed in, setting url to navigate to
if (popupParams.popup) {
popupWindow = popupParams.popup;
this.logger.verbosePii("0cgeo7", this.correlationId);
popupWindow.location.assign(urlNavigate);
}
else if (typeof popupParams.popup === "undefined") {
// Popup will be undefined if it was not passed in
this.logger.verbosePii("0c2awd", this.correlationId);
popupWindow = this.openSizedPopup(urlNavigate, popupParams);
}
// Popup will be null if popups are blocked
if (!popupWindow) {
throw createBrowserAuthError(emptyWindowError);
}
if (popupWindow.focus) {
popupWindow.focus();
}
this.currentWindow = popupWindow;
return popupWindow;
}
catch (e) {
this.logger.error("0dxfb9", this.correlationId);
throw createBrowserAuthError(popupWindowError);
}
}
/**
* Helper function to set popup window dimensions and position
* @param urlNavigate
* @param popupName
* @param popupWindowAttributes
* @returns
*/
openSizedPopup(urlNavigate, { popupName, popupWindowAttributes, popupWindowParent }) {
/**
* adding winLeft and winTop to account for dual monitor
* using screenLeft and screenTop for IE8 and earlier
*/
const winLeft = popupWindowParent.screenLeft
? popupWindowParent.screenLeft
: popupWindowParent.screenX;
const winTop = popupWindowParent.screenTop
? popupWindowParent.screenTop
: popupWindowParent.screenY;
/**
* window.innerWidth displays browser window"s height and width excluding toolbars
* using document.documentElement.clientWidth for IE8 and earlier
*/
const winWidth = popupWindowParent.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
const winHeight = popupWindowParent.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
let width = popupWindowAttributes.popupSize?.width;
let height = popupWindowAttributes.popupSize?.height;
let top = popupWindowAttributes.popupPosition?.top;
let left = popupWindowAttributes.popupPosition?.left;
if (!width || width < 0 || width > winWidth) {
this.logger.verbose("08vfmo", this.correlationId);
width = BrowserConstants.POPUP_WIDTH;
}
if (!height || height < 0 || height > winHeight) {
this.logger.verbose("09cxa0", this.correlationId);
height = BrowserConstants.POPUP_HEIGHT;
}
if (!top || top < 0 || top > winHeight) {
this.logger.verbose("1qh4wo", this.correlationId);
top = Math.max(0, winHeight / 2 - BrowserConstants.POPUP_HEIGHT / 2 + winTop);
}
if (!left || left < 0 || left > winWidth) {
this.logger.verbose("1sz3en", this.correlationId);
left = Math.max(0, winWidth / 2 - BrowserConstants.POPUP_WIDTH / 2 + winLeft);
}
return popupWindowParent.open(urlNavigate, popupName, `width=${width}, height=${height}, top=${top}, left=${left}, scrollbars=yes`);
}
/**
* Generates the name for the popup based on the client id and request
* @param clientId
* @param request
*/
generatePopupName(scopes, authority) {
return `${BrowserConstants.POPUP_NAME_PREFIX}.${this.config.auth.clientId}.${scopes.join("-")}.${authority}.${this.correlationId}`;
}
/**
* Generates the name for the popup based on the client id and request for logouts
* @param clientId
* @param request
*/
generateLogoutPopupName(request) {
const homeAccountId = request.account && request.account.homeAccountId;
return `${BrowserConstants.POPUP_NAME_PREFIX}.${this.config.auth.clientId}.${homeAccountId}.${this.correlationId}`;
}
}
export { PopupClient };
//# sourceMappingURL=PopupClient.mjs.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,452 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { invokeAsync, ProtocolMode, AuthError, Constants, PerformanceEvents, UrlUtils, ProtocolUtils, UrlString } from '@azure/msal-common/browser';
import { StandardInteractionClient, initializeAuthorizationRequest } from './StandardInteractionClient.mjs';
import { StandardInteractionClientInitializeAuthorizationRequest, GeneratePkceCodes, StandardInteractionClientCreateAuthCodeClient, StandardInteractionClientGetDiscoveredAuthority, GenerateEarKey, HandleResponseEar, HandleResponseCode } from '../telemetry/BrowserPerformanceEvents.mjs';
import { InteractionType, TemporaryCacheKeys, ApiId, INTERACTION_TYPE } from '../utils/BrowserConstants.mjs';
import { replaceHash, isInIframe, getHomepage, clearHash, getCurrentUri } from '../utils/BrowserUtils.mjs';
import { EventType } from '../event/EventType.mjs';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { validateInteractionType } from '../response/ResponseHandler.mjs';
import { getAuthCodeRequestUrl, getEARForm, getCodeForm, handleResponseEAR, handleResponseCode } from '../protocol/Authorize.mjs';
import { generatePkceCodes } from '../crypto/PkceGenerator.mjs';
import { isPlatformAuthAllowed } from '../broker/nativeBroker/PlatformAuthProvider.mjs';
import { generateEarKey } from '../crypto/BrowserCrypto.mjs';
import { initializeServerTelemetryManager, getDiscoveredAuthority, clearCacheOnLogout } from './BaseInteractionClient.mjs';
import { timedOut, noStateInHash, emptyNavigateUri } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
function getNavigationType() {
if (typeof window === "undefined" ||
typeof window.performance === "undefined" ||
typeof window.performance.getEntriesByType !== "function") {
return undefined;
}
const navigationEntries = window.performance.getEntriesByType("navigation");
const navigation = navigationEntries.length
? navigationEntries[0]
: undefined;
return navigation?.type;
}
class RedirectClient extends StandardInteractionClient {
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl, correlationId, platformAuthHandler) {
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, correlationId, platformAuthHandler);
this.nativeStorage = nativeStorageImpl;
}
/**
* Redirects the page to the /authorize endpoint of the IDP
* @param request
*/
async acquireToken(request) {
const validRequest = await invokeAsync(initializeAuthorizationRequest, StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(request, InteractionType.Redirect, this.config, this.browserCrypto, this.browserStorage, this.logger, this.performanceClient, this.correlationId);
validRequest.platformBroker = isPlatformAuthAllowed(this.config, this.logger, this.correlationId, this.platformAuthProvider, request.authenticationScheme);
const handleBackButton = (event) => {
// Clear temporary cache if the back button is clicked during the redirect flow.
if (event.persisted) {
this.logger.verbose("0udvtt", this.correlationId);
this.browserStorage.resetRequestCache(this.correlationId);
this.eventHandler.emitEvent(EventType.RESTORE_FROM_BFCACHE, this.correlationId, InteractionType.Redirect);
}
};
const redirectStartPage = this.getRedirectStartPage(request.redirectStartPage);
this.logger.verbosePii("0zao0a", this.correlationId);
// Cache start page, returns to this page after redirectUri if navigateToLoginRequestUrl is true
this.browserStorage.setTemporaryCache(TemporaryCacheKeys.ORIGIN_URI, redirectStartPage, true);
// Clear temporary cache if the back button is clicked during the redirect flow.
window.addEventListener("pageshow", handleBackButton);
try {
if (this.config.system.protocolMode === ProtocolMode.EAR) {
await this.executeEarFlow(validRequest);
}
else {
await this.executeCodeFlow(validRequest);
}
}
catch (e) {
if (e instanceof AuthError) {
e.setCorrelationId(this.correlationId);
}
window.removeEventListener("pageshow", handleBackButton);
throw e;
}
}
/**
* Executes auth code + PKCE flow
* @param request
* @returns
*/
async executeCodeFlow(request) {
const correlationId = request.correlationId;
const serverTelemetryManager = initializeServerTelemetryManager(ApiId.acquireTokenRedirect, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
const pkceCodes = await invokeAsync(generatePkceCodes, GeneratePkceCodes, this.logger, this.performanceClient, correlationId)(this.performanceClient, this.logger, correlationId);
const redirectRequest = {
...request,
codeChallenge: pkceCodes.challenge,
};
this.browserStorage.cacheAuthorizeRequest(redirectRequest, this.correlationId, pkceCodes.verifier);
try {
if (redirectRequest.httpMethod === Constants.HttpMethod.POST) {
return await this.executeCodeFlowWithPost(redirectRequest);
}
else {
// Initialize the client
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)({
serverTelemetryManager,
requestAuthority: redirectRequest.authority,
requestAzureCloudOptions: redirectRequest.azureCloudOptions,
requestExtraQueryParameters: redirectRequest.extraQueryParameters,
account: redirectRequest.account,
});
// Create acquire token url.
const navigateUrl = await invokeAsync(getAuthCodeRequestUrl, PerformanceEvents.GetAuthCodeUrl, this.logger, this.performanceClient, request.correlationId)(this.config, authClient.authority, redirectRequest, this.logger, this.performanceClient);
// Show the UI once the url has been created. Response will come back in the hash, which will be handled in the handleRedirectCallback function.
return await this.initiateAuthRequest(navigateUrl);
}
}
catch (e) {
if (e instanceof AuthError) {
e.setCorrelationId(this.correlationId);
serverTelemetryManager.cacheFailedRequest(e);
}
throw e;
}
}
/**
* Executes EAR flow
* @param request
*/
async executeEarFlow(request) {
const { correlationId, authority, azureCloudOptions, extraQueryParameters, account, } = request;
// Get the frame handle for the silent request
const discoveredAuthority = await invokeAsync(getDiscoveredAuthority, StandardInteractionClientGetDiscoveredAuthority, this.logger, this.performanceClient, correlationId)(this.config, this.correlationId, this.performanceClient, this.browserStorage, this.logger, authority, azureCloudOptions, extraQueryParameters, account);
const earJwk = await invokeAsync(generateEarKey, GenerateEarKey, this.logger, this.performanceClient, correlationId)();
const pkceCodes = await invokeAsync(generatePkceCodes, GeneratePkceCodes, this.logger, this.performanceClient, correlationId)(this.performanceClient, this.logger, correlationId);
const redirectRequest = {
...request,
earJwk: earJwk,
codeChallenge: pkceCodes.challenge,
};
this.browserStorage.cacheAuthorizeRequest(redirectRequest, this.correlationId, pkceCodes.verifier);
const form = await getEARForm(document, this.config, discoveredAuthority, redirectRequest, this.logger, this.performanceClient);
form.submit();
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(createBrowserAuthError(timedOut, "failed_to_redirect"));
}, this.config.system.redirectNavigationTimeout);
});
}
/**
* Executes classic Authorization Code flow with a POST request.
* @param request
*/
async executeCodeFlowWithPost(request) {
const correlationId = request.correlationId;
// Get the frame handle for the silent request
const discoveredAuthority = await invokeAsync(getDiscoveredAuthority, StandardInteractionClientGetDiscoveredAuthority, this.logger, this.performanceClient, correlationId)(this.config, this.correlationId, this.performanceClient, this.browserStorage, this.logger);
this.browserStorage.cacheAuthorizeRequest(request, this.correlationId);
const form = await getCodeForm(document, this.config, discoveredAuthority, request, this.logger, this.performanceClient);
form.submit();
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(createBrowserAuthError(timedOut, "failed_to_redirect"));
}, this.config.system.redirectNavigationTimeout);
});
}
/**
* Checks if navigateToLoginRequestUrl is set, and:
* - if true, performs logic to cache and navigate
* - if false, handles hash string and parses response
* @param hash {string} url hash
* @param parentMeasurement {InProgressPerformanceEvent} parent measurement
* @param request {CommonAuthorizationUrlRequest} request object
* @param pkceVerifier {string} PKCE verifier
* @param options {HandleRedirectPromiseOptions} options for handling redirect promise
*/
async handleRedirectPromise(request, pkceVerifier, parentMeasurement, options) {
const serverTelemetryManager = initializeServerTelemetryManager(ApiId.handleRedirectPromise, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
const navigateToLoginRequestUrl = options?.navigateToLoginRequestUrl ?? true;
try {
const [serverParams, responseString] = this.getRedirectResponse(options?.hash || "");
if (!serverParams) {
// Not a recognized server response hash or hash not associated with a redirect request
this.logger.info("1qmv0q", this.correlationId);
this.browserStorage.resetRequestCache(this.correlationId);
// Do not instrument "no_server_response" if user clicked back button
if (getNavigationType() !== "back_forward") {
parentMeasurement.event.errorCode = "no_server_response";
}
else {
this.logger.verbose("1eqegq", this.correlationId);
}
return null;
}
// If navigateToLoginRequestUrl is true, get the url where the redirect request was initiated
const loginRequestUrl = this.browserStorage.getTemporaryCache(TemporaryCacheKeys.ORIGIN_URI, this.correlationId, true) || "";
const loginRequestUrlNormalized = UrlUtils.normalizeUrlForComparison(loginRequestUrl);
const currentUrlNormalized = UrlUtils.normalizeUrlForComparison(window.location.href);
if (loginRequestUrlNormalized === currentUrlNormalized &&
navigateToLoginRequestUrl) {
// We are on the page we need to navigate to - handle hash
this.logger.verbose("11yred", this.correlationId);
if (loginRequestUrl.indexOf("#") > -1) {
// Replace current hash with non-msal hash, if present
replaceHash(loginRequestUrl);
}
const handleHashResult = await this.handleResponse(serverParams, request, pkceVerifier, serverTelemetryManager);
return handleHashResult;
}
else if (!navigateToLoginRequestUrl) {
this.logger.verbose("0v4sdv", this.correlationId);
return await this.handleResponse(serverParams, request, pkceVerifier, serverTelemetryManager);
}
else if (!isInIframe() ||
this.config.system.allowRedirectInIframe) {
/*
* Returned from authority using redirect - need to perform navigation before processing response
* Cache the hash to be retrieved after the next redirect
*/
this.browserStorage.setTemporaryCache(TemporaryCacheKeys.URL_HASH, responseString, true);
const navigationOptions = {
apiId: ApiId.handleRedirectPromise,
timeout: this.config.system.redirectNavigationTimeout,
noHistory: true,
};
/**
* Default behavior is to redirect to the start page and not process the hash now.
* The start page is expected to also call handleRedirectPromise which will process the hash in one of the checks above.
*/
let processHashOnRedirect = true;
if (!loginRequestUrl || loginRequestUrl === "null") {
// Redirect to home page if login request url is null (real null or the string null)
const homepage = getHomepage();
// Cache the homepage under ORIGIN_URI to ensure cached hash is processed on homepage
this.browserStorage.setTemporaryCache(TemporaryCacheKeys.ORIGIN_URI, homepage, true);
this.logger.warning("1dutq1", this.correlationId);
processHashOnRedirect =
await this.navigationClient.navigateInternal(homepage, navigationOptions);
}
else {
// Navigate to page that initiated the redirect request
this.logger.verbose("08jpy1", this.correlationId);
processHashOnRedirect =
await this.navigationClient.navigateInternal(loginRequestUrl, navigationOptions);
}
// If navigateInternal implementation returns false, handle the hash now
if (!processHashOnRedirect) {
return await this.handleResponse(serverParams, request, pkceVerifier, serverTelemetryManager);
}
}
return null;
}
catch (e) {
if (e instanceof AuthError) {
e.setCorrelationId(this.correlationId);
serverTelemetryManager.cacheFailedRequest(e);
}
throw e;
}
}
/**
* Gets the response hash for a redirect request
* Returns null if interactionType in the state value is not "redirect" or the hash does not contain known properties
* @param hash
*/
getRedirectResponse(userProvidedResponse) {
this.logger.verbose("1c5i8m", this.correlationId);
// Get current location hash from window or cache.
let responseString = userProvidedResponse;
if (!responseString) {
if (this.config.auth.OIDCOptions.responseMode ===
Constants.ResponseMode.QUERY) {
responseString = window.location.search;
}
else {
responseString = window.location.hash;
}
}
let response = UrlUtils.getDeserializedResponse(responseString);
if (response) {
try {
validateInteractionType(response, this.browserCrypto, InteractionType.Redirect);
}
catch (e) {
if (e instanceof AuthError) {
this.logger.error("0bkq6p", this.correlationId);
}
return [null, ""];
}
clearHash(window);
this.logger.verbose("00uvho", this.correlationId);
return [response, responseString];
}
const cachedHash = this.browserStorage.getTemporaryCache(TemporaryCacheKeys.URL_HASH, this.correlationId, true);
this.browserStorage.removeItem(this.browserStorage.generateCacheKey(TemporaryCacheKeys.URL_HASH));
if (cachedHash) {
response = UrlUtils.getDeserializedResponse(cachedHash);
if (response) {
this.logger.verbose("001671", this.correlationId);
return [response, cachedHash];
}
}
return [null, ""];
}
/**
* Checks if hash exists and handles in window.
* @param hash
* @param state
*/
async handleResponse(serverParams, request, codeVerifier, serverTelemetryManager) {
const state = serverParams.state;
if (!state) {
throw createBrowserAuthError(noStateInHash);
}
const { authority, azureCloudOptions, extraQueryParameters, account } = request;
if (serverParams.ear_jwe) {
const discoveredAuthority = await invokeAsync(getDiscoveredAuthority, StandardInteractionClientGetDiscoveredAuthority, this.logger, this.performanceClient, request.correlationId)(this.config, this.correlationId, this.performanceClient, this.browserStorage, this.logger, authority, azureCloudOptions, extraQueryParameters, account);
return invokeAsync(handleResponseEAR, HandleResponseEar, this.logger, this.performanceClient, request.correlationId)(request, serverParams, ApiId.acquireTokenRedirect, this.config, discoveredAuthority, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
}
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)({ serverTelemetryManager, requestAuthority: request.authority });
return invokeAsync(handleResponseCode, HandleResponseCode, this.logger, this.performanceClient, request.correlationId)(request, serverParams, codeVerifier, ApiId.acquireTokenRedirect, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
}
/**
* Redirects window to given URL.
* @param urlNavigate
* @param onRedirectNavigateRequest - onRedirectNavigate callback provided on the request
*/
async initiateAuthRequest(requestUrl) {
this.logger.verbose("0yaw2e", this.correlationId);
// Navigate if valid URL
if (requestUrl) {
this.logger.infoPii("1luf83", this.correlationId);
const navigationOptions = {
apiId: ApiId.acquireTokenRedirect,
timeout: this.config.system.redirectNavigationTimeout,
noHistory: false,
};
const onRedirectNavigate = this.config.auth.onRedirectNavigate;
// If onRedirectNavigate is implemented, invoke it and provide requestUrl
if (typeof onRedirectNavigate === "function") {
this.logger.verbose("1nehvl", this.correlationId);
const navigate = onRedirectNavigate(requestUrl);
// Returning false from onRedirectNavigate will stop navigation
if (navigate !== false) {
this.logger.verbose("1a0jxh", this.correlationId);
await this.navigationClient.navigateExternal(requestUrl, navigationOptions);
return;
}
else {
this.logger.verbose("09k5h5", this.correlationId);
return;
}
}
else {
// Navigate window to request URL
this.logger.verbose("0klwf7", this.correlationId);
await this.navigationClient.navigateExternal(requestUrl, navigationOptions);
return;
}
}
else {
// Throw error if request URL is empty.
this.logger.info("0rlh4e", this.correlationId);
throw createBrowserAuthError(emptyNavigateUri);
}
}
/**
* Use to log out the current user, and redirect the user to the postLogoutRedirectUri.
* Default behaviour is to redirect the user to `window.location.href`.
* @param logoutRequest
*/
async logout(logoutRequest) {
this.logger.verbose("1rkurh", this.correlationId);
const validLogoutRequest = this.initializeLogoutRequest(logoutRequest);
const serverTelemetryManager = initializeServerTelemetryManager(ApiId.logout, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
try {
this.eventHandler.emitEvent(EventType.LOGOUT_START, this.correlationId, InteractionType.Redirect, logoutRequest);
// Clear cache on logout
await clearCacheOnLogout(this.browserStorage, this.browserCrypto, this.logger, this.correlationId, validLogoutRequest.account);
const navigationOptions = {
apiId: ApiId.logout,
timeout: this.config.system.redirectNavigationTimeout,
noHistory: false,
};
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)({
serverTelemetryManager,
requestAuthority: logoutRequest && logoutRequest.authority,
requestExtraQueryParameters: logoutRequest?.extraQueryParameters,
account: (logoutRequest && logoutRequest.account) || undefined,
});
if (authClient.authority.protocolMode === ProtocolMode.OIDC) {
try {
authClient.authority.endSessionEndpoint;
}
catch {
if (validLogoutRequest.account?.homeAccountId) {
this.eventHandler.emitEvent(EventType.LOGOUT_SUCCESS, this.correlationId, InteractionType.Redirect, validLogoutRequest);
return;
}
}
}
// Redirect bridge requires "state" param to work properly
validLogoutRequest.state = ProtocolUtils.setRequestState(this.browserCrypto, validLogoutRequest.state || "", {
interactionType: InteractionType.Redirect,
});
// Create logout string and navigate user window to logout.
const logoutUri = authClient.getLogoutUri(validLogoutRequest);
if (validLogoutRequest.account?.homeAccountId) {
this.eventHandler.emitEvent(EventType.LOGOUT_SUCCESS, this.correlationId, InteractionType.Redirect, validLogoutRequest);
}
// Check if onRedirectNavigate is implemented, and invoke it if so
const onRedirectNavigate = this.config.auth.onRedirectNavigate;
if (typeof onRedirectNavigate === "function") {
const navigate = onRedirectNavigate(logoutUri);
if (navigate !== false) {
this.logger.verbose("06v57e", this.correlationId);
// Ensure interaction is in progress
if (!this.browserStorage.getInteractionInProgress()) {
this.browserStorage.setInteractionInProgress(true, INTERACTION_TYPE.SIGNOUT);
}
await this.navigationClient.navigateExternal(logoutUri, navigationOptions);
return;
}
else {
// Ensure interaction is not in progress
this.browserStorage.setInteractionInProgress(false);
this.logger.verbose("0xqes1", this.correlationId);
}
}
else {
// Ensure interaction is in progress
if (!this.browserStorage.getInteractionInProgress()) {
this.browserStorage.setInteractionInProgress(true, INTERACTION_TYPE.SIGNOUT);
}
await this.navigationClient.navigateExternal(logoutUri, navigationOptions);
return;
}
}
catch (e) {
if (e instanceof AuthError) {
e.setCorrelationId(this.correlationId);
serverTelemetryManager.cacheFailedRequest(e);
}
this.eventHandler.emitEvent(EventType.LOGOUT_FAILURE, this.correlationId, InteractionType.Redirect, null, e);
this.eventHandler.emitEvent(EventType.LOGOUT_END, this.correlationId, InteractionType.Redirect);
throw e;
}
this.eventHandler.emitEvent(EventType.LOGOUT_END, this.correlationId, InteractionType.Redirect);
}
/**
* Use to get the redirectStartPage either from request or use current window
* @param requestStartPage
*/
getRedirectStartPage(requestStartPage) {
const redirectStartPage = requestStartPage || window.location.href;
return UrlString.getAbsoluteUrl(redirectStartPage, getCurrentUri());
}
}
export { RedirectClient };
//# sourceMappingURL=RedirectClient.mjs.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,83 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { invokeAsync, PerformanceEvents, AuthError } from '@azure/msal-common/browser';
import { StandardInteractionClient, initializeAuthorizationRequest } from './StandardInteractionClient.mjs';
import { StandardInteractionClientInitializeAuthorizationRequest, StandardInteractionClientGetClientConfiguration } from '../telemetry/BrowserPerformanceEvents.mjs';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { InteractionType } from '../utils/BrowserConstants.mjs';
import { HybridSpaAuthorizationCodeClient } from './HybridSpaAuthorizationCodeClient.mjs';
import { InteractionHandler } from '../interaction_handler/InteractionHandler.mjs';
import { initializeServerTelemetryManager } from './BaseInteractionClient.mjs';
import { authCodeRequired, silentLogoutUnsupported } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class SilentAuthCodeClient extends StandardInteractionClient {
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, correlationId, platformAuthProvider) {
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, correlationId, platformAuthProvider);
this.apiId = apiId;
}
/**
* Acquires a token silently by redeeming an authorization code against the /token endpoint
* @param request
*/
async acquireToken(request) {
// Auth code payload is required
if (!request.code) {
throw createBrowserAuthError(authCodeRequired);
}
// Create silent request
const silentRequest = await invokeAsync(initializeAuthorizationRequest, StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(request, InteractionType.Silent, this.config, this.browserCrypto, this.browserStorage, this.logger, this.performanceClient,
/*
* correlationId is optional in request payload, while this.correlationId is always instantiated as request.correlationId || createGuid().
* Each auth request creates a new instance of *Client so we can safely use this.correlationId.
*/
this.correlationId);
const serverTelemetryManager = initializeServerTelemetryManager(this.apiId, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
try {
// Create auth code request (PKCE not needed)
const authCodeRequest = {
...silentRequest,
code: request.code,
};
// Initialize the client
const clientConfig = await invokeAsync(this.getClientConfiguration.bind(this), StandardInteractionClientGetClientConfiguration, this.logger, this.performanceClient, this.correlationId)({
serverTelemetryManager,
requestAuthority: silentRequest.authority,
requestAzureCloudOptions: silentRequest.azureCloudOptions,
requestExtraQueryParameters: silentRequest.extraQueryParameters,
account: silentRequest.account,
});
const authClient = new HybridSpaAuthorizationCodeClient(clientConfig, this.performanceClient);
this.logger.verbose("1uic5e", this.correlationId);
// Create silent handler
const interactionHandler = new InteractionHandler(authClient, this.browserStorage, authCodeRequest, this.logger, this.performanceClient);
// Handle auth code parameters from request
return await invokeAsync(interactionHandler.handleCodeResponseFromServer.bind(interactionHandler), PerformanceEvents.HandleCodeResponseFromServer, this.logger, this.performanceClient, this.correlationId)({
code: request.code,
msgraph_host: request.msGraphHost,
cloud_graph_host_name: request.cloudGraphHostName,
cloud_instance_host_name: request.cloudInstanceHostName,
}, silentRequest, this.apiId, false);
}
catch (e) {
if (e instanceof AuthError) {
e.setCorrelationId(this.correlationId);
serverTelemetryManager.cacheFailedRequest(e);
}
throw e;
}
}
/**
* Currently Unsupported
*/
logout() {
// Synchronous so we must reject
return Promise.reject(createBrowserAuthError(silentLogoutUnsupported));
}
}
export { SilentAuthCodeClient };
//# sourceMappingURL=SilentAuthCodeClient.mjs.map

View File

@ -0,0 +1 @@
{"version":3,"file":"SilentAuthCodeClient.mjs","sources":["../../src/interaction_client/SilentAuthCodeClient.ts"],"sourcesContent":[null],"names":["BrowserAuthErrorCodes.authCodeRequired","BrowserPerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest","BrowserPerformanceEvents.StandardInteractionClientGetClientConfiguration","BrowserAuthErrorCodes.silentLogoutUnsupported"],"mappings":"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"}

View File

@ -0,0 +1,59 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { StandardInteractionClient } from './StandardInteractionClient.mjs';
import { invokeAsync, SilentFlowClient } from '@azure/msal-common/browser';
import { StandardInteractionClientGetClientConfiguration, SilentFlowClientAcquireCachedToken } from '../telemetry/BrowserPerformanceEvents.mjs';
import { ApiId } from '../utils/BrowserConstants.mjs';
import { BrowserAuthError } from '../error/BrowserAuthError.mjs';
import { initializeServerTelemetryManager, clearCacheOnLogout } from './BaseInteractionClient.mjs';
import { cryptoKeyNotFound } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class SilentCacheClient extends StandardInteractionClient {
/**
* Returns unexpired tokens from the cache, if available
* @param silentRequest
*/
async acquireToken(silentRequest) {
// Telemetry manager only used to increment cacheHits here
const serverTelemetryManager = initializeServerTelemetryManager(ApiId.acquireTokenSilent_silentFlow, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
const clientConfig = await invokeAsync(this.getClientConfiguration.bind(this), StandardInteractionClientGetClientConfiguration, this.logger, this.performanceClient, this.correlationId)({
serverTelemetryManager,
requestAuthority: silentRequest.authority,
requestAzureCloudOptions: silentRequest.azureCloudOptions,
account: silentRequest.account,
});
const silentAuthClient = new SilentFlowClient(clientConfig, this.performanceClient);
this.logger.verbose("0wa871", this.correlationId);
try {
const response = await invokeAsync(silentAuthClient.acquireCachedToken.bind(silentAuthClient), SilentFlowClientAcquireCachedToken, this.logger, this.performanceClient, silentRequest.correlationId)(silentRequest);
const authResponse = response[0];
this.performanceClient.addFields({
fromCache: true,
}, silentRequest.correlationId);
return authResponse;
}
catch (error) {
if (error instanceof BrowserAuthError &&
error.errorCode === cryptoKeyNotFound) {
this.logger.verbose("06wena", this.correlationId);
}
throw error;
}
}
/**
* API to silenty clear the browser cache.
* @param logoutRequest
*/
logout(logoutRequest) {
this.logger.verbose("1rkurh", this.correlationId);
const validLogoutRequest = this.initializeLogoutRequest(logoutRequest);
return clearCacheOnLogout(this.browserStorage, this.browserCrypto, this.logger, this.correlationId, validLogoutRequest.account);
}
}
export { SilentCacheClient };
//# sourceMappingURL=SilentCacheClient.mjs.map

View File

@ -0,0 +1 @@
{"version":3,"file":"SilentCacheClient.mjs","sources":["../../src/interaction_client/SilentCacheClient.ts"],"sourcesContent":[null],"names":["BrowserPerformanceEvents.StandardInteractionClientGetClientConfiguration","BrowserPerformanceEvents.SilentFlowClientAcquireCachedToken","BrowserAuthErrorCodes.cryptoKeyNotFound"],"mappings":";;;;;;;;;;AAAA;;;AAGG;AAqBG,MAAO,iBAAkB,SAAQ,yBAAyB,CAAA;AAC5D;;;AAGG;IACH,MAAM,YAAY,CACd,aAAsC,EAAA;;AAGtC,QAAA,MAAM,sBAAsB,GAAG,gCAAgC,CAC3D,KAAK,CAAC,6BAA6B,EACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EACzB,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,MAAM,CACd,CAAC;AAEF,QAAA,MAAM,YAAY,GAAG,MAAM,WAAW,CAClC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EACtCA,+CAAwE,EACxE,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,aAAa,CACrB,CAAC;YACE,sBAAsB;YACtB,gBAAgB,EAAE,aAAa,CAAC,SAAS;YACzC,wBAAwB,EAAE,aAAa,CAAC,iBAAiB;YACzD,OAAO,EAAE,aAAa,CAAC,OAAO;AACjC,SAAA,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CACzC,YAAY,EACZ,IAAI,CAAC,iBAAiB,CACzB,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAA4B,EAAA,IAAA,CAAA,aAAA,CAAA,CAAE;QAElD,IAAI;AACA,YAAA,MAAM,QAAQ,GAAG,MAAM,WAAW,CAC9B,gBAAgB,CAAC,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAC1DC,kCAA2D,EAC3D,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,iBAAiB,EACtB,aAAa,CAAC,aAAa,CAC9B,CAAC,aAAa,CAAC,CAAC;AACjB,YAAA,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAyB,CAAC;AAEzD,YAAA,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAC5B;AACI,gBAAA,SAAS,EAAE,IAAI;AAClB,aAAA,EACD,aAAa,CAAC,aAAa,CAC9B,CAAC;AACF,YAAA,OAAO,YAAY,CAAC;AACvB,SAAA;AAAC,QAAA,OAAO,KAAK,EAAE;YACZ,IACI,KAAK,YAAY,gBAAgB;AACjC,gBAAA,KAAK,CAAC,SAAS,KAAKC,iBAAuC,EAC7D;gBACE,IAAI,CAAC,MAAM,CAAC,OAAO,CACf,QAAsH,EAAA,IAAA,CAAA,aAAA,CAAA,CAAA;AAG7H,aAAA;AACD,YAAA,MAAM,KAAK,CAAC;AACf,SAAA;KACJ;AAED;;;AAGG;AACH,IAAA,MAAM,CAAC,aAAiC,EAAA;QACpC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAuB,EAAA,IAAA,CAAA,aAAM,CAAA,CAAC;QAClD,MAAM,kBAAkB,GAAG,IAAI,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC;QACvE,OAAO,kBAAkB,CACrB,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,aAAa,EAClB,kBAAkB,CAAC,OAAO,CAC7B,CAAC;KACL;AACJ;;;;"}

View File

@ -0,0 +1,224 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { Constants, invokeAsync, ProtocolMode, AuthError, invoke, AuthorizeProtocol, PerformanceEvents } from '@azure/msal-common/browser';
import { StandardInteractionClient, initializeAuthorizationRequest } from './StandardInteractionClient.mjs';
import { StandardInteractionClientInitializeAuthorizationRequest, StandardInteractionClientCreateAuthCodeClient, SilentIframeClientTokenHelper, StandardInteractionClientGetDiscoveredAuthority, GenerateEarKey, GeneratePkceCodes, SilentHandlerInitiateAuthRequest, SilentHandlerMonitorIframeForHash, RemoveHiddenIframe, DeserializeResponse, HandleResponseCode, HandleResponseEar } from '../telemetry/BrowserPerformanceEvents.mjs';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { InteractionType, BrowserConstants } from '../utils/BrowserConstants.mjs';
import { initiateEarRequest, removeHiddenIframe, initiateCodeFlowWithPost, initiateCodeRequest } from '../interaction_handler/SilentHandler.mjs';
import { preconnect, waitForBridgeResponse } from '../utils/BrowserUtils.mjs';
import { deserializeResponse } from '../response/ResponseHandler.mjs';
import { handleResponseCode, handleResponseEAR, getAuthCodeRequestUrl } from '../protocol/Authorize.mjs';
import { generatePkceCodes } from '../crypto/PkceGenerator.mjs';
import { isPlatformAuthAllowed } from '../broker/nativeBroker/PlatformAuthProvider.mjs';
import { generateEarKey } from '../crypto/BrowserCrypto.mjs';
import { initializeServerTelemetryManager, getDiscoveredAuthority } from './BaseInteractionClient.mjs';
import { silentLogoutUnsupported } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class SilentIframeClient extends StandardInteractionClient {
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, nativeStorageImpl, correlationId, platformAuthProvider) {
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, correlationId, platformAuthProvider);
this.apiId = apiId;
this.nativeStorage = nativeStorageImpl;
}
/**
* Acquires a token silently by opening a hidden iframe to the /authorize endpoint with prompt=none or prompt=no_session
* @param request
*/
async acquireToken(request) {
// Check that we have some SSO data
if (!request.loginHint &&
!request.sid &&
(!request.account || !request.account.username)) {
this.logger.warning("1kl318", this.correlationId);
}
// Check the prompt value
const inputRequest = { ...request };
if (inputRequest.prompt) {
if (inputRequest.prompt !== Constants.PromptValue.NONE &&
inputRequest.prompt !== Constants.PromptValue.NO_SESSION) {
this.logger.warning("0bmctg", this.correlationId);
inputRequest.prompt = Constants.PromptValue.NONE;
}
}
else {
inputRequest.prompt = Constants.PromptValue.NONE;
}
// Create silent request
const silentRequest = await invokeAsync(initializeAuthorizationRequest, StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(inputRequest, InteractionType.Silent, this.config, this.browserCrypto, this.browserStorage, this.logger, this.performanceClient, this.correlationId);
silentRequest.platformBroker = isPlatformAuthAllowed(this.config, this.logger, this.correlationId, this.platformAuthProvider, silentRequest.authenticationScheme);
preconnect(silentRequest.authority);
if (this.config.system.protocolMode === ProtocolMode.EAR) {
return this.executeEarFlow(silentRequest);
}
else {
return this.executeCodeFlow(silentRequest);
}
}
/**
* Executes auth code + PKCE flow
* @param request
* @returns
*/
async executeCodeFlow(request) {
let authClient;
const serverTelemetryManager = initializeServerTelemetryManager(this.apiId, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
try {
// Initialize the client
authClient = await invokeAsync(this.createAuthCodeClient.bind(this), StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, request.correlationId)({
serverTelemetryManager,
requestAuthority: request.authority,
requestAzureCloudOptions: request.azureCloudOptions,
requestExtraQueryParameters: request.extraQueryParameters,
account: request.account,
});
return await invokeAsync(this.silentTokenHelper.bind(this), SilentIframeClientTokenHelper, this.logger, this.performanceClient, request.correlationId)(authClient, request);
}
catch (e) {
if (e instanceof AuthError) {
e.setCorrelationId(this.correlationId);
serverTelemetryManager.cacheFailedRequest(e);
}
if (!authClient ||
!(e instanceof AuthError) ||
e.errorCode !== BrowserConstants.INVALID_GRANT_ERROR) {
throw e;
}
this.performanceClient.addFields({
retryError: e.errorCode,
}, this.correlationId);
return await invokeAsync(this.silentTokenHelper.bind(this), SilentIframeClientTokenHelper, this.logger, this.performanceClient, this.correlationId)(authClient, request);
}
}
/**
* Executes EAR flow
* @param request
*/
async executeEarFlow(request) {
const { correlationId, authority, azureCloudOptions, extraQueryParameters, account, } = request;
const discoveredAuthority = await invokeAsync(getDiscoveredAuthority, StandardInteractionClientGetDiscoveredAuthority, this.logger, this.performanceClient, correlationId)(this.config, this.correlationId, this.performanceClient, this.browserStorage, this.logger, authority, azureCloudOptions, extraQueryParameters, account);
const earJwk = await invokeAsync(generateEarKey, GenerateEarKey, this.logger, this.performanceClient, correlationId)();
const pkceCodes = await invokeAsync(generatePkceCodes, GeneratePkceCodes, this.logger, this.performanceClient, correlationId)(this.performanceClient, this.logger, correlationId);
const silentRequest = {
...request,
earJwk: earJwk,
codeChallenge: pkceCodes.challenge,
};
const iframe = await invokeAsync(initiateEarRequest, SilentHandlerInitiateAuthRequest, this.logger, this.performanceClient, correlationId)(this.config, discoveredAuthority, silentRequest, this.logger, this.performanceClient);
const responseType = this.config.auth.OIDCOptions.responseMode;
let responseString;
try {
responseString = await invokeAsync(waitForBridgeResponse, SilentHandlerMonitorIframeForHash, this.logger, this.performanceClient, correlationId)(this.config.system.iframeBridgeTimeout, this.logger, this.browserCrypto, request, this.performanceClient, this.config.experimental);
}
finally {
invoke(removeHiddenIframe, RemoveHiddenIframe, this.logger, this.performanceClient, correlationId)(iframe);
}
const serverParams = invoke(deserializeResponse, DeserializeResponse, this.logger, this.performanceClient, correlationId)(responseString, responseType, this.logger, this.correlationId);
if (!serverParams.ear_jwe && serverParams.code) {
// If server doesn't support EAR, they may fallback to auth code flow instead
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, correlationId)({
serverTelemetryManager: initializeServerTelemetryManager(this.apiId, this.config.auth.clientId, correlationId, this.browserStorage, this.logger),
requestAuthority: request.authority,
requestAzureCloudOptions: request.azureCloudOptions,
requestExtraQueryParameters: request.extraQueryParameters,
account: request.account,
authority: discoveredAuthority,
});
return invokeAsync(handleResponseCode, HandleResponseCode, this.logger, this.performanceClient, correlationId)(silentRequest, serverParams, pkceCodes.verifier, this.apiId, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
}
else {
return invokeAsync(handleResponseEAR, HandleResponseEar, this.logger, this.performanceClient, correlationId)(silentRequest, serverParams, this.apiId, this.config, discoveredAuthority, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
}
}
/**
* Verifies SSO capability by making an iframe request to /authorize without exchanging the code for tokens.
* This is useful for verifying SSO capability in the background without the overhead of a full token exchange.
* @param request - The SSO silent request
* @returns true if SSO verification was successful with a valid authorization code, false otherwise
*/
async verifySso(request) {
const inputRequest = { ...request };
if (!inputRequest.prompt) {
inputRequest.prompt = Constants.PromptValue.NONE;
}
// Create silent request
const silentRequest = await invokeAsync(initializeAuthorizationRequest, StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(inputRequest, InteractionType.Silent, this.config, this.browserCrypto, this.browserStorage, this.logger, this.performanceClient, this.correlationId);
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)({
serverTelemetryManager: initializeServerTelemetryManager(this.apiId, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger),
requestAuthority: silentRequest.authority,
requestAzureCloudOptions: silentRequest.azureCloudOptions,
requestExtraQueryParameters: silentRequest.extraQueryParameters,
account: silentRequest.account,
});
const { serverParams } = await this.silentAuthorizeHelper(authClient, silentRequest);
const correlationId = silentRequest.correlationId;
// Validate the response - this checks for errors and validates state
AuthorizeProtocol.validateAuthorizationResponse(serverParams, silentRequest.state);
// Verify a valid authorization code is present
if (!serverParams.code) {
this.logger.warning("0y34ti", correlationId);
return false;
}
this.logger.verbose("0kkkcj", correlationId);
return true;
}
/**
* Currently Unsupported
*/
logout() {
// Synchronous so we must reject
return Promise.reject(createBrowserAuthError(silentLogoutUnsupported));
}
/**
* Helper which acquires an authorization code silently using a hidden iframe from given url
* using the scopes requested as part of the id, and exchanges the code for a set of OAuth tokens.
* @param navigateUrl
* @param userRequestScopes
*/
async silentTokenHelper(authClient, request) {
const { serverParams, pkceCodes } = await this.silentAuthorizeHelper(authClient, request);
return invokeAsync(handleResponseCode, HandleResponseCode, this.logger, this.performanceClient, request.correlationId)(request, serverParams, pkceCodes.verifier, this.apiId, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
}
/**
* Shared helper that generates PKCE codes, builds the /authorize URL,
* loads it in a hidden iframe, waits for the redirect-bridge response,
* and returns the deserialized server parameters along with the PKCE codes
* and the request that was sent.
*/
async silentAuthorizeHelper(authClient, request) {
const correlationId = request.correlationId;
const pkceCodes = await invokeAsync(generatePkceCodes, GeneratePkceCodes, this.logger, this.performanceClient, correlationId)(this.performanceClient, this.logger, correlationId);
const silentRequest = {
...request,
codeChallenge: pkceCodes.challenge,
};
let iframe;
if (request.httpMethod === Constants.HttpMethod.POST) {
iframe = await invokeAsync(initiateCodeFlowWithPost, SilentHandlerInitiateAuthRequest, this.logger, this.performanceClient, correlationId)(this.config, authClient.authority, silentRequest, this.logger, this.performanceClient);
}
else {
// Create authorize request url
const navigateUrl = await invokeAsync(getAuthCodeRequestUrl, PerformanceEvents.GetAuthCodeUrl, this.logger, this.performanceClient, correlationId)(this.config, authClient.authority, silentRequest, this.logger, this.performanceClient);
// Get the frame handle for the silent request
iframe = await invokeAsync(initiateCodeRequest, SilentHandlerInitiateAuthRequest, this.logger, this.performanceClient, correlationId)(navigateUrl, this.performanceClient, this.logger, correlationId);
}
const responseType = this.config.auth.OIDCOptions.responseMode;
// Wait for response from the redirect bridge.
let responseString;
try {
responseString = await invokeAsync(waitForBridgeResponse, SilentHandlerMonitorIframeForHash, this.logger, this.performanceClient, correlationId)(this.config.system.iframeBridgeTimeout, this.logger, this.browserCrypto, request, this.performanceClient, this.config.experimental);
}
finally {
invoke(removeHiddenIframe, RemoveHiddenIframe, this.logger, this.performanceClient, correlationId)(iframe);
}
const serverParams = invoke(deserializeResponse, DeserializeResponse, this.logger, this.performanceClient, correlationId)(responseString, responseType, this.logger, this.correlationId);
return { serverParams, pkceCodes, silentRequest };
}
}
export { SilentIframeClient };
//# sourceMappingURL=SilentIframeClient.mjs.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,76 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { StandardInteractionClient } from './StandardInteractionClient.mjs';
import { invokeAsync, RefreshTokenClient } from '@azure/msal-common/browser';
import { InitializeBaseRequest, RefreshTokenClientAcquireTokenByRefreshToken, StandardInteractionClientGetClientConfiguration } from '../telemetry/BrowserPerformanceEvents.mjs';
import { ApiId } from '../utils/BrowserConstants.mjs';
import { createBrowserAuthError } from '../error/BrowserAuthError.mjs';
import { initializeBaseRequest } from '../request/RequestHelpers.mjs';
import { getRedirectUri, initializeServerTelemetryManager } from './BaseInteractionClient.mjs';
import { silentLogoutUnsupported } from '../error/BrowserAuthErrorCodes.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class SilentRefreshClient extends StandardInteractionClient {
/**
* Exchanges the refresh token for new tokens
* @param request
*/
async acquireToken(request) {
const baseRequest = await invokeAsync(initializeBaseRequest, InitializeBaseRequest, this.logger, this.performanceClient, request.correlationId)(request, this.config, this.performanceClient, this.logger, this.correlationId);
const silentRequest = {
...request,
...baseRequest,
};
if (request.redirectUri) {
// Make sure any passed redirectUri is converted to an absolute URL - redirectUri is not a required parameter for refresh token redemption so only include if explicitly provided
silentRequest.redirectUri = getRedirectUri(request.redirectUri, this.config.auth.redirectUri, this.logger, this.correlationId);
}
const serverTelemetryManager = initializeServerTelemetryManager(ApiId.acquireTokenSilent_silentFlow, this.config.auth.clientId, this.correlationId, this.browserStorage, this.logger);
const refreshTokenClient = await this.createRefreshTokenClient({
serverTelemetryManager,
authorityUrl: silentRequest.authority,
azureCloudOptions: silentRequest.azureCloudOptions,
account: silentRequest.account,
});
// Send request to renew token. Auth module will throw errors if token cannot be renewed.
return invokeAsync(refreshTokenClient.acquireTokenByRefreshToken.bind(refreshTokenClient), RefreshTokenClientAcquireTokenByRefreshToken, this.logger, this.performanceClient, request.correlationId)(silentRequest, ApiId.acquireTokenSilent_silentFlow).catch((e) => {
e.setCorrelationId(this.correlationId);
serverTelemetryManager.cacheFailedRequest(e);
throw e;
});
}
/**
* Currently Unsupported
*/
logout() {
// Synchronous so we must reject
return Promise.reject(createBrowserAuthError(silentLogoutUnsupported));
}
/**
* Creates a Refresh Client with the given authority, or the default authority.
* @param params {
* serverTelemetryManager: ServerTelemetryManager;
* authorityUrl?: string;
* azureCloudOptions?: AzureCloudOptions;
* extraQueryParams?: StringDict;
* account?: AccountInfo;
* }
*/
async createRefreshTokenClient(params) {
// Create auth module.
const clientConfig = await invokeAsync(this.getClientConfiguration.bind(this), StandardInteractionClientGetClientConfiguration, this.logger, this.performanceClient, this.correlationId)({
serverTelemetryManager: params.serverTelemetryManager,
requestAuthority: params.authorityUrl,
requestAzureCloudOptions: params.azureCloudOptions,
requestExtraQueryParameters: params.extraQueryParameters,
account: params.account,
});
return new RefreshTokenClient(clientConfig, this.performanceClient);
}
}
export { SilentRefreshClient };
//# sourceMappingURL=SilentRefreshClient.mjs.map

View File

@ -0,0 +1 @@
{"version":3,"file":"SilentRefreshClient.mjs","sources":["../../src/interaction_client/SilentRefreshClient.ts"],"sourcesContent":[null],"names":["BrowserPerformanceEvents.InitializeBaseRequest","BrowserPerformanceEvents.RefreshTokenClientAcquireTokenByRefreshToken","BrowserAuthErrorCodes.silentLogoutUnsupported","BrowserPerformanceEvents.StandardInteractionClientGetClientConfiguration"],"mappings":";;;;;;;;;;;AAAA;;;AAGG;AA0BG,MAAO,mBAAoB,SAAQ,yBAAyB,CAAA;AAC9D;;;AAGG;IACH,MAAM,YAAY,CACd,OAAgC,EAAA;AAEhC,QAAA,MAAM,WAAW,GAAG,MAAM,WAAW,CACjC,qBAAqB,EACrBA,qBAA8C,EAC9C,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,iBAAiB,EACtB,OAAO,CAAC,aAAa,CACxB,CACG,OAAO,EACP,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,aAAa,CACrB,CAAC;AACF,QAAA,MAAM,aAAa,GAA4B;AAC3C,YAAA,GAAG,OAAO;AACV,YAAA,GAAG,WAAW;SACjB,CAAC;QAEF,IAAI,OAAO,CAAC,WAAW,EAAE;;YAErB,aAAa,CAAC,WAAW,GAAG,cAAc,CACtC,OAAO,CAAC,WAAW,EACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAC5B,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,aAAa,CACrB,CAAC;AACL,SAAA;AAED,QAAA,MAAM,sBAAsB,GAAG,gCAAgC,CAC3D,KAAK,CAAC,6BAA6B,EACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EACzB,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,MAAM,CACd,CAAC;AAEF,QAAA,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC;YAC3D,sBAAsB;YACtB,YAAY,EAAE,aAAa,CAAC,SAAS;YACrC,iBAAiB,EAAE,aAAa,CAAC,iBAAiB;YAClD,OAAO,EAAE,aAAa,CAAC,OAAO;AACjC,SAAA,CAAC,CAAC;;AAEH,QAAA,OAAO,WAAW,CACd,kBAAkB,CAAC,0BAA0B,CAAC,IAAI,CAC9C,kBAAkB,CACrB,EACDC,4CAAqE,EACrE,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,iBAAiB,EACtB,OAAO,CAAC,aAAa,CACxB,CAAC,aAAa,EAAE,KAAK,CAAC,6BAA6B,CAAC,CAAC,KAAK,CACvD,CAAC,CAAY,KAAI;AACZ,YAAA,CAAe,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACtD,YAAA,sBAAsB,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AAC7C,YAAA,MAAM,CAAC,CAAC;AACZ,SAAC,CAC6B,CAAC;KACtC;AAED;;AAEG;IACH,MAAM,GAAA;;QAEF,OAAO,OAAO,CAAC,MAAM,CACjB,sBAAsB,CAClBC,uBAA6C,CAChD,CACJ,CAAC;KACL;AAED;;;;;;;;;AASG;IACO,MAAM,wBAAwB,CAAC,MAMxC,EAAA;;AAEG,QAAA,MAAM,YAAY,GAAG,MAAM,WAAW,CAClC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EACtCC,+CAAwE,EACxE,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,aAAa,CACrB,CAAC;YACE,sBAAsB,EAAE,MAAM,CAAC,sBAAsB;YACrD,gBAAgB,EAAE,MAAM,CAAC,YAAY;YACrC,wBAAwB,EAAE,MAAM,CAAC,iBAAiB;YAClD,2BAA2B,EAAE,MAAM,CAAC,oBAAoB;YACxD,OAAO,EAAE,MAAM,CAAC,OAAO;AAC1B,SAAA,CAAC,CAAC;QACH,OAAO,IAAI,kBAAkB,CAAC,YAAY,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;KACvE;AACJ;;;;"}

View File

@ -0,0 +1,217 @@
/*! @azure/msal-browser v5.11.0 2026-05-19 */
'use strict';
import { UrlString, invokeAsync, AuthorizationCodeClient, ProtocolUtils } from '@azure/msal-common/browser';
import { BaseInteractionClient, getDiscoveredAuthority, getRedirectUri } from './BaseInteractionClient.mjs';
import { StandardInteractionClientGetClientConfiguration, StandardInteractionClientGetDiscoveredAuthority, InitializeBaseRequest } from '../telemetry/BrowserPerformanceEvents.mjs';
import { BrowserConstants } from '../utils/BrowserConstants.mjs';
import { version } from '../packageMetadata.mjs';
import { getCurrentUri } from '../utils/BrowserUtils.mjs';
import { createNewGuid } from '../crypto/BrowserCrypto.mjs';
import { initializeBaseRequest, validateRequestMethod } from '../request/RequestHelpers.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Defines the class structure and helper functions used by the "standard", non-brokered auth flows (popup, redirect, silent (RT), silent (iframe))
*/
class StandardInteractionClient extends BaseInteractionClient {
/**
* Initializer for the logout request.
* @param logoutRequest
*/
initializeLogoutRequest(logoutRequest) {
this.logger.verbose("0546u4", this.correlationId);
const validLogoutRequest = {
correlationId: this.correlationId,
...logoutRequest,
};
/**
* Set logout_hint to be login_hint from ID Token Claims if present
* and logoutHint attribute wasn't manually set in logout request
*/
if (logoutRequest) {
// If logoutHint isn't set and an account was passed in, try to extract logoutHint from account loginHint or ID Token Claims
if (!logoutRequest.logoutHint) {
if (logoutRequest.account) {
const logoutHint = logoutRequest.account.loginHint ||
this.getLogoutHintFromIdTokenClaims(logoutRequest.account);
if (logoutHint) {
this.logger.verbose("0d7s8p", this.correlationId);
validLogoutRequest.logoutHint = logoutHint;
}
}
else {
this.logger.verbose("0pdtc3", this.correlationId);
}
}
else {
this.logger.verbose("12k4l4", this.correlationId);
}
}
else {
this.logger.verbose("07ndze", this.correlationId);
}
/*
* Only set redirect uri if logout request isn't provided or the set uri isn't null.
* Otherwise, use passed uri, config, or current page.
*/
if (!logoutRequest || logoutRequest.postLogoutRedirectUri !== null) {
if (logoutRequest && logoutRequest.postLogoutRedirectUri) {
this.logger.verbose("1vamm6", validLogoutRequest.correlationId);
validLogoutRequest.postLogoutRedirectUri =
UrlString.getAbsoluteUrl(logoutRequest.postLogoutRedirectUri, getCurrentUri());
}
else if (this.config.auth.postLogoutRedirectUri === null) {
this.logger.verbose("15m5g7", validLogoutRequest.correlationId);
}
else if (this.config.auth.postLogoutRedirectUri) {
this.logger.verbose("1f4xlz", validLogoutRequest.correlationId);
validLogoutRequest.postLogoutRedirectUri =
UrlString.getAbsoluteUrl(this.config.auth.postLogoutRedirectUri, getCurrentUri());
}
else {
this.logger.verbose("17s5rf", validLogoutRequest.correlationId);
validLogoutRequest.postLogoutRedirectUri =
UrlString.getAbsoluteUrl(getCurrentUri(), getCurrentUri());
}
}
else {
this.logger.verbose("0ljv63", validLogoutRequest.correlationId);
}
return validLogoutRequest;
}
/**
* Parses login_hint ID Token Claim out of AccountInfo object to be used as
* logout_hint in end session request.
* @param account
*/
getLogoutHintFromIdTokenClaims(account) {
const idTokenClaims = account.idTokenClaims;
if (idTokenClaims) {
if (idTokenClaims.login_hint) {
this.logger.verbose("0u5bmc", this.correlationId);
return idTokenClaims.login_hint;
}
else {
this.logger.verbose("0mvp54", this.correlationId);
}
}
else {
this.logger.verbose("1e7bdp", this.correlationId);
}
return null;
}
/**
* Creates an Authorization Code Client with the given authority, or the default authority.
* @param params {
* serverTelemetryManager: ServerTelemetryManager;
* authorityUrl?: string;
* requestAzureCloudOptions?: AzureCloudOptions;
* requestExtraQueryParameters?: StringDict;
* account?: AccountInfo;
* }
*/
async createAuthCodeClient(params) {
// Create auth module.
const clientConfig = await invokeAsync(this.getClientConfiguration.bind(this), StandardInteractionClientGetClientConfiguration, this.logger, this.performanceClient, this.correlationId)(params);
return new AuthorizationCodeClient(clientConfig, this.performanceClient);
}
/**
* Creates a Client Configuration object with the given request authority, or the default authority.
* @param params {
* serverTelemetryManager: ServerTelemetryManager;
* requestAuthority?: string;
* requestAzureCloudOptions?: AzureCloudOptions;
* requestExtraQueryParameters?: boolean;
* account?: AccountInfo;
* }
*/
async getClientConfiguration(params) {
const { serverTelemetryManager, requestAuthority, requestAzureCloudOptions, requestExtraQueryParameters, account, } = params;
const discoveredAuthority = params.authority ||
(await invokeAsync(getDiscoveredAuthority, StandardInteractionClientGetDiscoveredAuthority, this.logger, this.performanceClient, this.correlationId)(this.config, this.correlationId, this.performanceClient, this.browserStorage, this.logger, requestAuthority, requestAzureCloudOptions, requestExtraQueryParameters, account));
const logger = this.config.system.loggerOptions;
return {
authOptions: {
clientId: this.config.auth.clientId,
authority: discoveredAuthority,
clientCapabilities: this.config.auth.clientCapabilities,
redirectUri: this.config.auth.redirectUri,
isMcp: this.config.auth.isMcp,
},
systemOptions: {
tokenRenewalOffsetSeconds: this.config.system.tokenRenewalOffsetSeconds,
preventCorsPreflight: true,
},
loggerOptions: {
loggerCallback: logger.loggerCallback,
piiLoggingEnabled: logger.piiLoggingEnabled,
logLevel: logger.logLevel,
correlationId: this.correlationId,
},
cryptoInterface: this.browserCrypto,
networkInterface: this.networkClient,
storageInterface: this.browserStorage,
serverTelemetryManager: serverTelemetryManager,
libraryInfo: {
sku: BrowserConstants.MSAL_SKU,
version: version,
cpu: "",
os: "",
},
telemetry: this.config.telemetry,
};
}
}
/**
* Helper to initialize required request parameters for interactive APIs and ssoSilent().
*
* @param request - The authentication request object (RedirectRequest, PopupRequest, or SsoSilentRequest).
* @param interactionType - The type of interaction (e.g., redirect, popup, silent).
* @param config - The browser configuration object.
* @param browserCrypto - The cryptographic interface for browser operations.
* @param browserStorage - The browser storage manager instance.
* @param logger - The logger instance for logging messages.
* @param performanceClient - The performance client for telemetry.
* @param correlationId - The correlation ID for the request.
* @returns A promise that resolves to a CommonAuthorizationUrlRequest object with initialized parameters.
*/
async function initializeAuthorizationRequest(request, interactionType, config, browserCrypto, browserStorage, logger, performanceClient, correlationId) {
const redirectUri = getRedirectUri(request.redirectUri, config.auth.redirectUri, logger, correlationId);
if (new URL(redirectUri).origin !== new URL(window.location.href).origin) {
logger.warning("08qbvw", correlationId);
performanceClient.addFields({ isRedirectUriCrossOrigin: true }, correlationId);
}
const browserState = {
interactionType: interactionType,
};
const state = ProtocolUtils.setRequestState(browserCrypto, (request && request.state) || "", browserState);
const baseRequest = await invokeAsync(initializeBaseRequest, InitializeBaseRequest, logger, performanceClient, correlationId)({ ...request, correlationId: correlationId }, config, performanceClient, logger, correlationId);
const interactionRequest = {
...baseRequest,
redirectUri: redirectUri,
state: state,
nonce: request.nonce || createNewGuid(),
responseMode: config.auth.OIDCOptions.responseMode,
};
const validatedRequest = {
...interactionRequest,
httpMethod: validateRequestMethod(interactionRequest, config.system.protocolMode),
};
// Skip active account lookup if either login hint or session id is set
if (request.loginHint || request.sid) {
return validatedRequest;
}
const account = request.account || browserStorage.getActiveAccount(correlationId);
if (account) {
logger.verbose("1eqlb3", correlationId);
logger.verbosePii("0tf99t", correlationId);
validatedRequest.account = account;
}
return validatedRequest;
}
export { StandardInteractionClient, initializeAuthorizationRequest };
//# sourceMappingURL=StandardInteractionClient.mjs.map

File diff suppressed because one or more lines are too long