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,199 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import {
AccountInfo,
Constants,
InProgressPerformanceEvent,
IPerformanceClient,
Logger,
PerformanceClient,
PerformanceEvent,
SubMeasurement,
} from "@azure/msal-common/browser";
import { Configuration } from "../config/Configuration.js";
import { name, version } from "../packageMetadata.js";
import { BrowserCacheLocation } from "../utils/BrowserConstants.js";
import * as BrowserCrypto from "../crypto/BrowserCrypto.js";
import { BROWSER_PERF_ENABLED_KEY } from "../cache/CacheKeys.js";
import { getNetworkInfo } from "../utils/MsalFrameStatsUtils.js";
/**
* Returns browser performance measurement module if session flag is enabled. Returns undefined otherwise.
*/
function getPerfMeasurementModule() {
let sessionStorage: Storage | undefined;
try {
sessionStorage = window[BrowserCacheLocation.SessionStorage];
const perfEnabled = sessionStorage?.getItem(BROWSER_PERF_ENABLED_KEY);
if (Number(perfEnabled) === 1) {
return import("./BrowserPerformanceMeasurement.js");
}
// Mute errors if it's a non-browser environment or cookies are blocked.
} catch (e) {}
return undefined;
}
/**
* Returns boolean, indicating whether browser supports window.performance.now() function.
*/
function supportsBrowserPerformanceNow(): boolean {
return (
typeof window !== "undefined" &&
typeof window.performance !== "undefined" &&
typeof window.performance.now === "function"
);
}
/**
* Returns event duration in milliseconds using window performance API if available. Returns undefined otherwise.
* @param startTime {DOMHighResTimeStamp | undefined}
* @returns {number | undefined}
*/
function getPerfDurationMs(
startTime: DOMHighResTimeStamp | undefined
): number | undefined {
if (!startTime || !supportsBrowserPerformanceNow()) {
return undefined;
}
return Math.round(window.performance.now() - startTime);
}
export class BrowserPerformanceClient
extends PerformanceClient
implements IPerformanceClient
{
constructor(configuration: Configuration, intFields?: Set<string>) {
super(
configuration.auth.clientId,
configuration.auth.authority || `${Constants.DEFAULT_AUTHORITY}`,
new Logger(
configuration.system?.loggerOptions || {},
name,
version
),
name,
version,
configuration.telemetry?.application || {
appName: "",
appVersion: "",
},
intFields
);
}
generateId(): string {
return BrowserCrypto.createNewGuid();
}
private getPageVisibility(): string | null {
return document.visibilityState?.toString() || null;
}
private getOnlineStatus(): boolean | null {
return typeof navigator !== "undefined" ? navigator.onLine : null;
}
private deleteIncompleteSubMeasurements(
inProgressEvent: InProgressPerformanceEvent
): void {
void getPerfMeasurementModule()?.then((module) => {
const rootEvent = this.eventsByCorrelationId.get(
inProgressEvent.event.correlationId
);
const isRootEvent =
rootEvent &&
rootEvent.eventId === inProgressEvent.event.eventId;
const incompleteMeasurements: SubMeasurement[] = [];
if (isRootEvent && rootEvent?.incompleteSubMeasurements) {
rootEvent.incompleteSubMeasurements.forEach(
(subMeasurement: SubMeasurement) => {
incompleteMeasurements.push({ ...subMeasurement });
}
);
}
// Clean up remaining marks for incomplete sub-measurements
module.BrowserPerformanceMeasurement.flushMeasurements(
inProgressEvent.event.correlationId,
incompleteMeasurements
);
});
}
/**
* Starts measuring performance for a given operation. Returns a function that should be used to end the measurement.
* Also captures browser page visibilityState.
*
* @param {PerformanceEvents} measureName
* @param {?string} [correlationId]
* @returns {((event?: Partial<PerformanceEvent>) => PerformanceEvent| null)}
*/
startMeasurement(
measureName: string,
correlationId?: string
): InProgressPerformanceEvent {
// Capture page visibilityState and then invoke start/end measurement
const startPageVisibility = this.getPageVisibility();
const startOnlineStatus = this.getOnlineStatus();
const inProgressEvent = super.startMeasurement(
measureName,
correlationId
);
const startTime: number | undefined = supportsBrowserPerformanceNow()
? window.performance.now()
: undefined;
const browserMeasurement = getPerfMeasurementModule()?.then(
(module) => {
return new module.BrowserPerformanceMeasurement(
measureName,
inProgressEvent.event.correlationId
);
}
);
void browserMeasurement?.then((measurement) =>
measurement.startMeasurement()
);
return {
...inProgressEvent,
end: (
event?: Partial<PerformanceEvent>,
error?: unknown,
account?: AccountInfo
): PerformanceEvent | null => {
const networkInfo = getNetworkInfo();
const res = inProgressEvent.end(
{
...event,
startPageVisibility,
startOnlineStatus,
endPageVisibility: this.getPageVisibility(),
durationMs: getPerfDurationMs(startTime),
networkEffectiveType: networkInfo.effectiveType,
networkRtt: networkInfo.rtt,
},
error,
account
);
void browserMeasurement?.then((measurement) =>
measurement.endMeasurement()
);
this.deleteIncompleteSubMeasurements(inProgressEvent);
return res;
},
discard: () => {
inProgressEvent.discard();
void browserMeasurement?.then((measurement) =>
measurement.flushMeasurement()
);
this.deleteIncompleteSubMeasurements(inProgressEvent);
},
};
}
}

View File

@ -0,0 +1,195 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* acquireTokenFromCache (msal-browser).
* Internal API for acquiring token from cache
*/
export const AcquireTokenFromCache = "acquireTokenFromCache";
/**
* acquireTokenByRefreshToken API (msal-browser and msal-node).
* Used to renew an access token using a refresh token against the token endpoint.
*/
export const AcquireTokenByRefreshToken = "acquireTokenByRefreshToken";
/**
* acquireTokenSilentAsync (msal-browser).
* Internal API for acquireTokenSilent.
*/
export const AcquireTokenSilentAsync = "acquireTokenSilentAsync";
/**
* getPublicKeyThumbprint API in CryptoOpts class (msal-browser).
* Used to generate a public/private keypair and generate a public key thumbprint for pop requests.
*/
export const CryptoOptsGetPublicKeyThumbprint =
"cryptoOptsGetPublicKeyThumbprint";
/**
* signJwt API in CryptoOpts class (msal-browser).
* Used to signed a pop token.
*/
export const CryptoOptsSignJwt = "cryptoOptsSignJwt";
/**
* acquireToken API in the SilentCacheClient class (msal-browser).
* Used to read access tokens from the cache.
*/
export const SilentCacheClientAcquireToken = "silentCacheClientAcquireToken";
/**
* acquireToken API in the SilentIframeClient class (msal-browser).
* Used to acquire a new set of tokens from the authorize endpoint in a hidden iframe.
*/
export const SilentIframeClientAcquireToken = "silentIframeClientAcquireToken";
export const AwaitConcurrentIframe = "awaitConcurrentIframe"; // Time spent waiting for a concurrent iframe to complete
/**
* acquireToken API in SilentRereshClient (msal-browser).
* Used to acquire a new set of tokens from the token endpoint using a refresh token.
*/
export const SilentRefreshClientAcquireToken =
"silentRefreshClientAcquireToken";
/**
* getDiscoveredAuthority API in StandardInteractionClient class (msal-browser).
* Used to load authority metadata for a request.
*/
export const StandardInteractionClientGetDiscoveredAuthority =
"standardInteractionClientGetDiscoveredAuthority";
/**
* acquireToken APIs in msal-browser.
* Used to make an /authorize endpoint call with native brokering enabled.
*/
export const FetchAccountIdWithNativeBroker = "fetchAccountIdWithNativeBroker";
/**
* acquireToken API in NativeInteractionClient class (msal-browser).
* Used to acquire a token from Native component when native brokering is enabled.
*/
export const NativeInteractionClientAcquireToken =
"nativeInteractionClientAcquireToken";
export const NativeInteractionClientAcquireTokenRedirect =
"nativeInteractionClientAcquireToken";
/**
* Time spent creating default headers for requests to token endpoint
*/
export const BaseClientCreateTokenRequestHeaders =
"baseClientCreateTokenRequestHeaders";
/**
* acquireTokenByRefreshToken API in RefreshTokenClient (msal-common).
*/
export const RefreshTokenClientAcquireTokenByRefreshToken =
"refreshTokenClientAcquireTokenByRefreshToken";
/**
* acquireTokenBySilentIframe (msal-browser).
* Internal API for acquiring token by silent Iframe
*/
export const AcquireTokenBySilentIframe = "acquireTokenBySilentIframe";
/**
* Internal API for initializing base request in BaseInteractionClient (msal-browser)
*/
export const InitializeBaseRequest = "initializeBaseRequest";
/**
* Internal API for initializing silent request in SilentCacheClient (msal-browser)
*/
export const InitializeSilentRequest = "initializeSilentRequest";
export const InitializeCache = "initializeCache";
/**
* Helper function in SilentIframeClient class (msal-browser).
*/
export const SilentIframeClientTokenHelper = "silentIframeClientTokenHelper";
/**
* SilentHandler
*/
export const SilentHandlerInitiateAuthRequest =
"silentHandlerInitiateAuthRequest";
export const SilentHandlerMonitorIframeForHash =
"silentHandlerMonitorIframeForHash";
export const SilentHandlerLoadFrame = "silentHandlerLoadFrame";
export const SilentHandlerLoadFrameSync = "silentHandlerLoadFrameSync";
/**
* Helper functions in StandardInteractionClient class (msal-browser)
*/
export const StandardInteractionClientCreateAuthCodeClient =
"standardInteractionClientCreateAuthCodeClient";
export const StandardInteractionClientGetClientConfiguration =
"standardInteractionClientGetClientConfiguration";
export const StandardInteractionClientInitializeAuthorizationRequest =
"standardInteractionClientInitializeAuthorizationRequest";
export const SilentFlowClientAcquireCachedToken =
"silentFlowClientAcquireCachedToken";
export const GetStandardParams = "getStandardParams";
export const HandleCodeResponse = "handleCodeResponse";
export const HandleResponseEar = "handleResponseEar";
export const HandleResponsePlatformBroker = "handleResponsePlatformBroker";
export const HandleResponseCode = "handleResponseCode";
export const AuthClientAcquireToken = "authClientAcquireToken";
export const DeserializeResponse = "deserializeResponse";
export const AuthorityFactoryCreateDiscoveredInstance =
"authorityFactoryCreateDiscoveredInstance";
export const AuthorityResolveEndpointsFromLocalSources =
"authorityResolveEndpointsFromLocalSources";
export const AcquireTokenByCodeAsync = "acquireTokenByCodeAsync";
export const HandleRedirectPromiseMeasurement = "handleRedirectPromise";
export const HandleNativeRedirectPromiseMeasurement =
"handleNativeRedirectPromise";
export const NativeMessageHandlerHandshake = "nativeMessageHandlerHandshake";
export const NativeGenerateAuthResult = "nativeGenerateAuthResult";
export const RemoveHiddenIframe = "removeHiddenIframe";
export const ImportExistingCache = "importExistingCache";
export const SetUserData = "setUserData";
/**
* Crypto Operations
*/
export const GeneratePkceCodes = "generatePkceCodes";
export const GenerateCodeVerifier = "generateCodeVerifier";
export const GenerateCodeChallengeFromVerifier =
"generateCodeChallengeFromVerifier";
export const Sha256Digest = "sha256Digest";
export const GetRandomValues = "getRandomValues";
export const GenerateHKDF = "generateHKDF";
export const GenerateBaseKey = "generateBaseKey";
export const Base64Decode = "base64Decode";
export const UrlEncodeArr = "urlEncodeArr";
export const Encrypt = "encrypt";
export const Decrypt = "decrypt";
export const GenerateEarKey = "generateEarKey";
export const DecryptEarResponse = "decryptEarResponse";
export const LoadAccount = "loadAccount";
export const LoadIdToken = "loadIdToken";
export const LoadAccessToken = "loadAccessToken";
export const LoadRefreshToken = "loadRefreshToken";
/**
* Background telemetry measurement that tracks whether a late bridge response
* arrives after the iframe timeout has already fired.
*/
export const WaitForBridgeLateResponse = "waitForBridgeLateResponse";

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import {
IPerformanceMeasurement,
SubMeasurement,
} from "@azure/msal-common/browser";
export class BrowserPerformanceMeasurement implements IPerformanceMeasurement {
private readonly measureName: string;
private readonly correlationId: string;
private readonly startMark: string;
private readonly endMark: string;
constructor(name: string, correlationId: string) {
this.correlationId = correlationId;
this.measureName = BrowserPerformanceMeasurement.makeMeasureName(
name,
correlationId
);
this.startMark = BrowserPerformanceMeasurement.makeStartMark(
name,
correlationId
);
this.endMark = BrowserPerformanceMeasurement.makeEndMark(
name,
correlationId
);
}
private static makeMeasureName(name: string, correlationId: string) {
return `msal.measure.${name}.${correlationId}`;
}
private static makeStartMark(name: string, correlationId: string) {
return `msal.start.${name}.${correlationId}`;
}
private static makeEndMark(name: string, correlationId: string) {
return `msal.end.${name}.${correlationId}`;
}
static supportsBrowserPerformance(): boolean {
return (
typeof window !== "undefined" &&
typeof window.performance !== "undefined" &&
typeof window.performance.mark === "function" &&
typeof window.performance.measure === "function" &&
typeof window.performance.clearMarks === "function" &&
typeof window.performance.clearMeasures === "function" &&
typeof window.performance.getEntriesByName === "function"
);
}
/**
* Flush browser marks and measurements.
* @param {string} correlationId
* @param {SubMeasurement} measurements
*/
public static flushMeasurements(
correlationId: string,
measurements: SubMeasurement[]
): void {
if (BrowserPerformanceMeasurement.supportsBrowserPerformance()) {
try {
measurements.forEach((measurement) => {
const measureName =
BrowserPerformanceMeasurement.makeMeasureName(
measurement.name,
correlationId
);
const entriesForMeasurement =
window.performance.getEntriesByName(
measureName,
"measure"
);
if (entriesForMeasurement.length > 0) {
window.performance.clearMeasures(measureName);
window.performance.clearMarks(
BrowserPerformanceMeasurement.makeStartMark(
measureName,
correlationId
)
);
window.performance.clearMarks(
BrowserPerformanceMeasurement.makeEndMark(
measureName,
correlationId
)
);
}
});
} catch (e) {
// Silently catch and return null
}
}
}
startMeasurement(): void {
if (BrowserPerformanceMeasurement.supportsBrowserPerformance()) {
try {
window.performance.mark(this.startMark);
} catch (e) {
// Silently catch
}
}
}
endMeasurement(): void {
if (BrowserPerformanceMeasurement.supportsBrowserPerformance()) {
try {
window.performance.mark(this.endMark);
window.performance.measure(
this.measureName,
this.startMark,
this.endMark
);
} catch (e) {
// Silently catch
}
}
}
flushMeasurement(): number | null {
if (BrowserPerformanceMeasurement.supportsBrowserPerformance()) {
try {
const entriesForMeasurement =
window.performance.getEntriesByName(
this.measureName,
"measure"
);
if (entriesForMeasurement.length > 0) {
const durationMs = entriesForMeasurement[0].duration;
window.performance.clearMeasures(this.measureName);
window.performance.clearMarks(this.startMark);
window.performance.clearMarks(this.endMark);
return durationMs;
}
} catch (e) {
// Silently catch and return null
}
}
return null;
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* acquireTokenSilent API (msal-browser and msal-node).
* Used to silently acquire a new access token (from the cache or the network).
*/
export const AcquireTokenSilent = "acquireTokenSilent";
/**
* acquireTokenByCode API (msal-browser and msal-node).
* Used to acquire tokens by trading an authorization code against the token endpoint.
*/
export const AcquireTokenByCode = "acquireTokenByCode";
/**
* acquireTokenPopup (msal-browser).
* Used to acquire a new access token interactively through pop ups
*/
export const AcquireTokenPopup = "acquireTokenPopup";
/**
* acquireTokenPreRedirect (msal-browser).
* First part of the redirect flow.
* Used to acquire a new access token interactively through redirects.
*/
export const AcquireTokenPreRedirect = "acquireTokenPreRedirect";
/**
* acquireTokenRedirect (msal-browser).
* Second part of the redirect flow.
* Used to acquire a new access token interactively through redirects.
*/
export const AcquireTokenRedirect = "acquireTokenRedirect";
/**
* ssoSilent API (msal-browser).
* Used to silently acquire an authorization code and set of tokens using a hidden iframe.
*/
export const SsoSilent = "ssoSilent";
// Initialize client application
export const InitializeClientApplication = "initializeClientApplication";
// Update cache storage
export const LocalStorageUpdated = "localStorageUpdated";
// Load external tokens
export const LoadExternalTokens = "loadExternalTokens";
/**
* SSO capability verification call (msal-browser).
* Fire-and-forget SSO verification call made after interactive authentication completes.
*/
export const SsoCapable = "ssoCapable";
// Wait for late response from bridge after timeout has already occurred
export const WaitForBridgeLateResponse = "waitForBridgeLateResponse";