@azure/msal-browser
Advanced tools
Comparing version 4.1.0 to 4.2.0
@@ -13,2 +13,3 @@ import { CommonAuthorizationCodeRequest, ICrypto, AccountEntity, IdTokenEntity, AccessTokenEntity, RefreshTokenEntity, AppMetadataEntity, CacheManager, ServerTelemetryEntity, ThrottlingEntity, Logger, AuthorityMetadataEntity, AccountInfo, TokenKeys, CredentialType, CacheRecord, IPerformanceClient, StaticAuthorityOptions, StoreInCache } from "@azure/msal-common/browser"; | ||
import { CookieStorage } from "./CookieStorage.js"; | ||
import { EventHandler } from "../event/EventHandler.js"; | ||
/** | ||
@@ -27,3 +28,4 @@ * This class implements the cache storage interface for MSAL through browser local or session storage. | ||
protected performanceClient: IPerformanceClient; | ||
constructor(clientId: string, cacheConfig: Required<CacheOptions>, cryptoImpl: ICrypto, logger: Logger, performanceClient: IPerformanceClient, staticAuthorityOptions?: StaticAuthorityOptions); | ||
private eventHandler; | ||
constructor(clientId: string, cacheConfig: Required<CacheOptions>, cryptoImpl: ICrypto, logger: Logger, performanceClient: IPerformanceClient, eventHandler: EventHandler, staticAuthorityOptions?: StaticAuthorityOptions); | ||
initialize(correlationId: string): Promise<void>; | ||
@@ -56,3 +58,3 @@ /** | ||
*/ | ||
addAccountKeyToMap(key: string): void; | ||
addAccountKeyToMap(key: string): boolean; | ||
/** | ||
@@ -69,2 +71,7 @@ * Remove an account from the key map | ||
/** | ||
* Removes credentials associated with the provided account | ||
* @param account | ||
*/ | ||
removeAccountContext(account: AccountEntity): Promise<void>; | ||
/** | ||
* Removes given idToken from the cache and from the key map | ||
@@ -308,3 +315,3 @@ * @param key | ||
} | ||
export declare const DEFAULT_BROWSER_CACHE_MANAGER: (clientId: string, logger: Logger, performanceClient: IPerformanceClient) => BrowserCacheManager; | ||
export declare const DEFAULT_BROWSER_CACHE_MANAGER: (clientId: string, logger: Logger, performanceClient: IPerformanceClient, eventHandler: EventHandler) => BrowserCacheManager; | ||
//# sourceMappingURL=BrowserCacheManager.d.ts.map |
import { IWindowStorage } from "./IWindowStorage.js"; | ||
export declare const SameSiteOptions: { | ||
readonly Lax: "Lax"; | ||
readonly None: "None"; | ||
}; | ||
export type SameSiteOptions = (typeof SameSiteOptions)[keyof typeof SameSiteOptions]; | ||
export declare class CookieStorage implements IWindowStorage<string> { | ||
@@ -6,3 +11,3 @@ initialize(): Promise<void>; | ||
getUserData(): string | null; | ||
setItem(key: string, value: string, cookieLifeDays?: number, secure?: boolean): void; | ||
setItem(key: string, value: string, cookieLifeDays?: number, secure?: boolean, sameSite?: SameSiteOptions): void; | ||
setUserData(): Promise<void>; | ||
@@ -9,0 +14,0 @@ removeItem(key: string): void; |
@@ -10,2 +10,3 @@ import { IPerformanceClient, Logger } from "@azure/msal-common/browser"; | ||
private encryptionCookie?; | ||
private broadcast; | ||
constructor(clientId: string, logger: Logger, performanceClient: IPerformanceClient); | ||
@@ -47,3 +48,4 @@ initialize(correlationId: string): Promise<void>; | ||
private getContext; | ||
private updateCache; | ||
} | ||
//# sourceMappingURL=LocalStorage.d.ts.map |
@@ -101,3 +101,4 @@ import { SystemOptions, LoggerOptions, INetworkModule, ProtocolMode, OIDCOptions, AzureCloudOptions, ApplicationTelemetry, IPerformanceClient } from "@azure/msal-common/browser"; | ||
/** | ||
* If set, MSAL sets the "Secure" flag on cookies so they can only be sent over HTTPS. By default this flag is set to false. | ||
* If set, MSAL sets the "Secure" flag on cookies so they can only be sent over HTTPS. By default this flag is set to true. | ||
* @deprecated This option will be removed in a future major version and all cookies set will include the Secure attribute. | ||
*/ | ||
@@ -104,0 +105,0 @@ secureCookies?: boolean; |
@@ -51,3 +51,2 @@ import { AccountInfo, INetworkModule, Logger, CommonSilentFlowRequest, ICrypto, PerformanceCallbackFunction, IPerformanceClient, BaseAuthRequest, AccountFilter } from "@azure/msal-common/browser"; | ||
private acquireTokenByCodeAsyncMeasurement?; | ||
private listeningToStorageEvents; | ||
/** | ||
@@ -313,2 +312,3 @@ * @constructor | ||
* Adds event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window | ||
* @deprecated These events will be raised by default and this method will be removed in a future major version. | ||
*/ | ||
@@ -318,9 +318,6 @@ enableAccountStorageEvents(): void; | ||
* Removes event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window | ||
* @deprecated These events will be raised by default and this method will be removed in a future major version. | ||
*/ | ||
disableAccountStorageEvents(): void; | ||
/** | ||
* Emit account added/removed events when cached accounts are changed in a different tab or frame | ||
*/ | ||
protected handleAccountCacheChange(e: StorageEvent): void; | ||
/** | ||
* Gets the token cache for the application. | ||
@@ -327,0 +324,0 @@ */ |
@@ -40,2 +40,3 @@ import { CommonAuthorizationUrlRequest, CommonSilentFlowRequest, PerformanceCallbackFunction, AccountInfo, Logger, ICrypto, IPerformanceClient, AccountFilter } from "@azure/msal-common/browser"; | ||
protected readonly performanceClient: IPerformanceClient; | ||
private readonly eventHandler; | ||
protected readonly browserCrypto: ICrypto; | ||
@@ -42,0 +43,0 @@ protected isBrowserEnvironment: boolean; |
@@ -8,2 +8,3 @@ import { Logger } from "@azure/msal-common/browser"; | ||
private logger; | ||
private broadcastChannel; | ||
constructor(logger?: Logger); | ||
@@ -30,3 +31,21 @@ /** | ||
emitEvent(eventType: EventType, interactionType?: InteractionType, payload?: EventPayload, error?: EventError): void; | ||
/** | ||
* Invoke registered callbacks | ||
* @param message | ||
*/ | ||
private invokeCallbacks; | ||
/** | ||
* Wrapper around invokeCallbacks to handle broadcast events received from other tabs/instances | ||
* @param event | ||
*/ | ||
private invokeCrossTabCallbacks; | ||
/** | ||
* Listen for events broadcasted from other tabs/instances | ||
*/ | ||
subscribeCrossTab(): void; | ||
/** | ||
* Unsubscribe from broadcast events | ||
*/ | ||
unsubscribeCrossTab(): void; | ||
} | ||
//# sourceMappingURL=EventHandler.d.ts.map |
export declare const name = "@azure/msal-browser"; | ||
export declare const version = "4.1.0"; | ||
export declare const version = "4.2.0"; | ||
//# sourceMappingURL=packageMetadata.d.ts.map |
@@ -13,2 +13,3 @@ import { CommonAuthorizationCodeRequest, ICrypto, AccountEntity, IdTokenEntity, AccessTokenEntity, RefreshTokenEntity, AppMetadataEntity, CacheManager, ServerTelemetryEntity, ThrottlingEntity, Logger, AuthorityMetadataEntity, AccountInfo, TokenKeys, CredentialType, CacheRecord, IPerformanceClient, StaticAuthorityOptions, StoreInCache } from "@azure/msal-common/browser"; | ||
import { CookieStorage } from "./CookieStorage.js"; | ||
import { EventHandler } from "../event/EventHandler.js"; | ||
/** | ||
@@ -27,3 +28,4 @@ * This class implements the cache storage interface for MSAL through browser local or session storage. | ||
protected performanceClient: IPerformanceClient; | ||
constructor(clientId: string, cacheConfig: Required<CacheOptions>, cryptoImpl: ICrypto, logger: Logger, performanceClient: IPerformanceClient, staticAuthorityOptions?: StaticAuthorityOptions); | ||
private eventHandler; | ||
constructor(clientId: string, cacheConfig: Required<CacheOptions>, cryptoImpl: ICrypto, logger: Logger, performanceClient: IPerformanceClient, eventHandler: EventHandler, staticAuthorityOptions?: StaticAuthorityOptions); | ||
initialize(correlationId: string): Promise<void>; | ||
@@ -56,3 +58,3 @@ /** | ||
*/ | ||
addAccountKeyToMap(key: string): void; | ||
addAccountKeyToMap(key: string): boolean; | ||
/** | ||
@@ -69,2 +71,7 @@ * Remove an account from the key map | ||
/** | ||
* Removes credentials associated with the provided account | ||
* @param account | ||
*/ | ||
removeAccountContext(account: AccountEntity): Promise<void>; | ||
/** | ||
* Removes given idToken from the cache and from the key map | ||
@@ -308,3 +315,3 @@ * @param key | ||
} | ||
export declare const DEFAULT_BROWSER_CACHE_MANAGER: (clientId: string, logger: Logger, performanceClient: IPerformanceClient) => BrowserCacheManager; | ||
export declare const DEFAULT_BROWSER_CACHE_MANAGER: (clientId: string, logger: Logger, performanceClient: IPerformanceClient, eventHandler: EventHandler) => BrowserCacheManager; | ||
//# sourceMappingURL=BrowserCacheManager.d.ts.map |
import { IWindowStorage } from "./IWindowStorage.js"; | ||
export declare const SameSiteOptions: { | ||
readonly Lax: "Lax"; | ||
readonly None: "None"; | ||
}; | ||
export type SameSiteOptions = (typeof SameSiteOptions)[keyof typeof SameSiteOptions]; | ||
export declare class CookieStorage implements IWindowStorage<string> { | ||
@@ -6,3 +11,3 @@ initialize(): Promise<void>; | ||
getUserData(): string | null; | ||
setItem(key: string, value: string, cookieLifeDays?: number, secure?: boolean): void; | ||
setItem(key: string, value: string, cookieLifeDays?: number, secure?: boolean, sameSite?: SameSiteOptions): void; | ||
setUserData(): Promise<void>; | ||
@@ -9,0 +14,0 @@ removeItem(key: string): void; |
@@ -10,2 +10,3 @@ import { IPerformanceClient, Logger } from "@azure/msal-common/browser"; | ||
private encryptionCookie?; | ||
private broadcast; | ||
constructor(clientId: string, logger: Logger, performanceClient: IPerformanceClient); | ||
@@ -47,3 +48,4 @@ initialize(correlationId: string): Promise<void>; | ||
private getContext; | ||
private updateCache; | ||
} | ||
//# sourceMappingURL=LocalStorage.d.ts.map |
@@ -101,3 +101,4 @@ import { SystemOptions, LoggerOptions, INetworkModule, ProtocolMode, OIDCOptions, AzureCloudOptions, ApplicationTelemetry, IPerformanceClient } from "@azure/msal-common/browser"; | ||
/** | ||
* If set, MSAL sets the "Secure" flag on cookies so they can only be sent over HTTPS. By default this flag is set to false. | ||
* If set, MSAL sets the "Secure" flag on cookies so they can only be sent over HTTPS. By default this flag is set to true. | ||
* @deprecated This option will be removed in a future major version and all cookies set will include the Secure attribute. | ||
*/ | ||
@@ -104,0 +105,0 @@ secureCookies?: boolean; |
@@ -51,3 +51,2 @@ import { AccountInfo, INetworkModule, Logger, CommonSilentFlowRequest, ICrypto, PerformanceCallbackFunction, IPerformanceClient, BaseAuthRequest, AccountFilter } from "@azure/msal-common/browser"; | ||
private acquireTokenByCodeAsyncMeasurement?; | ||
private listeningToStorageEvents; | ||
/** | ||
@@ -313,2 +312,3 @@ * @constructor | ||
* Adds event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window | ||
* @deprecated These events will be raised by default and this method will be removed in a future major version. | ||
*/ | ||
@@ -318,9 +318,6 @@ enableAccountStorageEvents(): void; | ||
* Removes event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window | ||
* @deprecated These events will be raised by default and this method will be removed in a future major version. | ||
*/ | ||
disableAccountStorageEvents(): void; | ||
/** | ||
* Emit account added/removed events when cached accounts are changed in a different tab or frame | ||
*/ | ||
protected handleAccountCacheChange(e: StorageEvent): void; | ||
/** | ||
* Gets the token cache for the application. | ||
@@ -327,0 +324,0 @@ */ |
@@ -40,2 +40,3 @@ import { CommonAuthorizationUrlRequest, CommonSilentFlowRequest, PerformanceCallbackFunction, AccountInfo, Logger, ICrypto, IPerformanceClient, AccountFilter } from "@azure/msal-common/browser"; | ||
protected readonly performanceClient: IPerformanceClient; | ||
private readonly eventHandler; | ||
protected readonly browserCrypto: ICrypto; | ||
@@ -42,0 +43,0 @@ protected isBrowserEnvironment: boolean; |
@@ -8,2 +8,3 @@ import { Logger } from "@azure/msal-common/browser"; | ||
private logger; | ||
private broadcastChannel; | ||
constructor(logger?: Logger); | ||
@@ -30,3 +31,21 @@ /** | ||
emitEvent(eventType: EventType, interactionType?: InteractionType, payload?: EventPayload, error?: EventError): void; | ||
/** | ||
* Invoke registered callbacks | ||
* @param message | ||
*/ | ||
private invokeCallbacks; | ||
/** | ||
* Wrapper around invokeCallbacks to handle broadcast events received from other tabs/instances | ||
* @param event | ||
*/ | ||
private invokeCrossTabCallbacks; | ||
/** | ||
* Listen for events broadcasted from other tabs/instances | ||
*/ | ||
subscribeCrossTab(): void; | ||
/** | ||
* Unsubscribe from broadcast events | ||
*/ | ||
unsubscribeCrossTab(): void; | ||
} | ||
//# sourceMappingURL=EventHandler.d.ts.map |
export declare const name = "@azure/msal-browser"; | ||
export declare const version = "4.1.0"; | ||
export declare const version = "4.2.0"; | ||
//# sourceMappingURL=packageMetadata.d.ts.map |
@@ -13,3 +13,3 @@ { | ||
}, | ||
"version": "4.1.0", | ||
"version": "4.2.0", | ||
"description": "Microsoft Authentication Library for js", | ||
@@ -64,3 +64,3 @@ "keywords": [ | ||
"lint:fix": "npm run lint -- --fix", | ||
"test": "jest", | ||
"test": "jest --forceExit", | ||
"test:coverage": "jest --coverage", | ||
@@ -108,4 +108,4 @@ "test:coverage:only": "npm run clean:coverage && npm run test:coverage", | ||
"dependencies": { | ||
"@azure/msal-common": "15.1.0" | ||
"@azure/msal-common": "15.1.1" | ||
} | ||
} |
@@ -69,2 +69,4 @@ /* | ||
import { getAccountKeys, getTokenKeys } from "./CacheHelpers.js"; | ||
import { EventType } from "../event/EventType.js"; | ||
import { EventHandler } from "../event/EventHandler.js"; | ||
@@ -91,2 +93,4 @@ /** | ||
protected performanceClient: IPerformanceClient; | ||
// Event Handler | ||
private eventHandler: EventHandler; | ||
@@ -99,2 +103,3 @@ constructor( | ||
performanceClient: IPerformanceClient, | ||
eventHandler: EventHandler, | ||
staticAuthorityOptions?: StaticAuthorityOptions | ||
@@ -121,2 +126,3 @@ ) { | ||
this.performanceClient = performanceClient; | ||
this.eventHandler = eventHandler; | ||
} | ||
@@ -191,3 +197,18 @@ | ||
)(key, JSON.stringify(account), correlationId); | ||
this.addAccountKeyToMap(key); | ||
const wasAdded = this.addAccountKeyToMap(key); | ||
/** | ||
* @deprecated - Remove this in next major version in favor of more consistent LOGIN event | ||
*/ | ||
if ( | ||
this.cacheConfig.cacheLocation === | ||
BrowserCacheLocation.LocalStorage && | ||
wasAdded | ||
) { | ||
this.eventHandler.emitEvent( | ||
EventType.ACCOUNT_ADDED, | ||
undefined, | ||
account.getAccountInfo() | ||
); | ||
} | ||
} | ||
@@ -207,3 +228,3 @@ | ||
*/ | ||
addAccountKeyToMap(key: string): void { | ||
addAccountKeyToMap(key: string): boolean { | ||
this.logger.trace("BrowserCacheManager.addAccountKeyToMap called"); | ||
@@ -224,2 +245,3 @@ this.logger.tracePii( | ||
); | ||
return true; | ||
} else { | ||
@@ -229,2 +251,3 @@ this.logger.verbose( | ||
); | ||
return false; | ||
} | ||
@@ -270,2 +293,23 @@ } | ||
/** | ||
* Removes credentials associated with the provided account | ||
* @param account | ||
*/ | ||
async removeAccountContext(account: AccountEntity): Promise<void> { | ||
await super.removeAccountContext(account); | ||
/** | ||
* @deprecated - Remove this in next major version in favor of more consistent LOGOUT event | ||
*/ | ||
if ( | ||
this.cacheConfig.cacheLocation === BrowserCacheLocation.LocalStorage | ||
) { | ||
this.eventHandler.emitEvent( | ||
EventType.ACCOUNT_REMOVED, | ||
undefined, | ||
account.getAccountInfo() | ||
); | ||
} | ||
} | ||
/** | ||
* Removes given idToken from the cache and from the key map | ||
@@ -804,2 +848,3 @@ * @param key | ||
} | ||
this.eventHandler.emitEvent(EventType.ACTIVE_ACCOUNT_CHANGED); | ||
} | ||
@@ -1494,3 +1539,4 @@ | ||
logger: Logger, | ||
performanceClient: IPerformanceClient | ||
performanceClient: IPerformanceClient, | ||
eventHandler: EventHandler | ||
): BrowserCacheManager => { | ||
@@ -1510,4 +1556,5 @@ const cacheOptions: Required<CacheOptions> = { | ||
logger, | ||
performanceClient | ||
performanceClient, | ||
eventHandler | ||
); | ||
}; |
@@ -15,2 +15,9 @@ /* | ||
export const SameSiteOptions = { | ||
Lax: "Lax", | ||
None: "None", | ||
} as const; | ||
export type SameSiteOptions = | ||
(typeof SameSiteOptions)[keyof typeof SameSiteOptions]; | ||
export class CookieStorage implements IWindowStorage<string> { | ||
@@ -44,7 +51,8 @@ initialize(): Promise<void> { | ||
cookieLifeDays?: number, | ||
secure: boolean = true | ||
secure: boolean = true, | ||
sameSite: SameSiteOptions = SameSiteOptions.Lax | ||
): void { | ||
let cookieStr = `${encodeURIComponent(key)}=${encodeURIComponent( | ||
value | ||
)};path=/;SameSite=Lax;`; | ||
)};path=/;SameSite=${sameSite};`; | ||
@@ -56,3 +64,4 @@ if (cookieLifeDays) { | ||
if (secure) { | ||
if (secure || sameSite === SameSiteOptions.None) { | ||
// SameSite None requires Secure flag | ||
cookieStr += "Secure;"; | ||
@@ -59,0 +68,0 @@ } |
@@ -32,3 +32,3 @@ /* | ||
} from "../error/BrowserConfigurationAuthError.js"; | ||
import { CookieStorage } from "./CookieStorage.js"; | ||
import { CookieStorage, SameSiteOptions } from "./CookieStorage.js"; | ||
import { IWindowStorage } from "./IWindowStorage.js"; | ||
@@ -40,2 +40,3 @@ import { MemoryStorage } from "./MemoryStorage.js"; | ||
const ENCRYPTION_KEY = "msal.cache.encryption"; | ||
const BROADCAST_CHANNEL_NAME = "msal.broadcast.cache"; | ||
@@ -60,2 +61,3 @@ type EncryptionCookie = { | ||
private encryptionCookie?: EncryptionCookie; | ||
private broadcast: BroadcastChannel; | ||
@@ -77,2 +79,3 @@ constructor( | ||
this.performanceClient = performanceClient; | ||
this.broadcast = new BroadcastChannel(BROADCAST_CHANNEL_NAME); | ||
} | ||
@@ -150,4 +153,14 @@ | ||
}; | ||
cookies.setItem(ENCRYPTION_KEY, JSON.stringify(cookieData)); | ||
cookies.setItem( | ||
ENCRYPTION_KEY, | ||
JSON.stringify(cookieData), | ||
0, // Expiration - 0 means cookie will be cleared at the end of the browser session | ||
true, // Secure flag | ||
SameSiteOptions.None // SameSite must be None to support iframed apps | ||
); | ||
} | ||
// Register listener for cache updates in other tabs | ||
this.broadcast.addEventListener("message", this.updateCache.bind(this)); | ||
} | ||
@@ -198,6 +211,20 @@ | ||
this.setItem(key, JSON.stringify(encryptedData)); | ||
// Notify other frames to update their in-memory cache | ||
this.broadcast.postMessage({ | ||
key: key, | ||
value: value, | ||
context: this.getContext(key), | ||
}); | ||
} | ||
removeItem(key: string): void { | ||
this.memoryStorage.removeItem(key); | ||
if (this.memoryStorage.containsKey(key)) { | ||
this.memoryStorage.removeItem(key); | ||
this.broadcast.postMessage({ | ||
key: key, | ||
value: null, | ||
context: this.getContext(key), | ||
}); | ||
} | ||
window.localStorage.removeItem(key); | ||
@@ -375,2 +402,37 @@ } | ||
} | ||
private updateCache(event: MessageEvent): void { | ||
this.logger.trace("Updating internal cache from broadcast event"); | ||
const perfMeasurement = this.performanceClient.startMeasurement( | ||
PerformanceEvents.LocalStorageUpdated | ||
); | ||
perfMeasurement.add({ isBackground: true }); | ||
const { key, value, context } = event.data; | ||
if (!key) { | ||
this.logger.error("Broadcast event missing key"); | ||
perfMeasurement.end({ success: false, errorCode: "noKey" }); | ||
return; | ||
} | ||
if (context && context !== this.clientId) { | ||
this.logger.trace( | ||
`Ignoring broadcast event from clientId: ${context}` | ||
); | ||
perfMeasurement.end({ | ||
success: false, | ||
errorCode: "contextMismatch", | ||
}); | ||
return; | ||
} | ||
if (!value) { | ||
this.memoryStorage.removeItem(key); | ||
this.logger.verbose("Removed item from internal cache"); | ||
} else { | ||
this.memoryStorage.setItem(key, value); | ||
this.logger.verbose("Updated item in internal cache"); | ||
} | ||
perfMeasurement.end({ success: true }); | ||
} | ||
} |
@@ -139,3 +139,4 @@ /* | ||
/** | ||
* If set, MSAL sets the "Secure" flag on cookies so they can only be sent over HTTPS. By default this flag is set to false. | ||
* If set, MSAL sets the "Secure" flag on cookies so they can only be sent over HTTPS. By default this flag is set to true. | ||
* @deprecated This option will be removed in a future major version and all cookies set will include the Secure attribute. | ||
*/ | ||
@@ -142,0 +143,0 @@ secureCookies?: boolean; |
@@ -114,2 +114,3 @@ /* | ||
this.eventHandler = new EventHandler(this.logger); | ||
// Initialize the browser storage class. | ||
@@ -123,2 +124,3 @@ this.browserStorage = this.operatingContext.isBrowserEnvironment() | ||
this.performanceClient, | ||
this.eventHandler, | ||
buildStaticAuthorityOptions(this.config.auth) | ||
@@ -129,7 +131,6 @@ ) | ||
this.logger, | ||
this.performanceClient | ||
this.performanceClient, | ||
this.eventHandler | ||
); | ||
this.eventHandler = new EventHandler(this.logger); | ||
this.nestedAppAuthAdapter = new NestedAppAuthAdapter( | ||
@@ -136,0 +137,0 @@ this.config.auth.clientId, |
@@ -43,2 +43,3 @@ /* | ||
import { EventType } from "../event/EventType.js"; | ||
import { EventHandler } from "../event/EventHandler.js"; | ||
@@ -75,2 +76,5 @@ /** | ||
// Event handler | ||
private readonly eventHandler: EventHandler; | ||
// Crypto interface implementation | ||
@@ -103,2 +107,4 @@ protected readonly browserCrypto: ICrypto; | ||
this.eventHandler = new EventHandler(this.logger); | ||
// Initialize the browser storage class. | ||
@@ -112,2 +118,3 @@ this.browserStorage = this.isBrowserEnvironment | ||
this.performanceClient, | ||
this.eventHandler, | ||
undefined | ||
@@ -118,3 +125,4 @@ ) | ||
this.logger, | ||
this.performanceClient | ||
this.performanceClient, | ||
this.eventHandler | ||
); | ||
@@ -121,0 +129,0 @@ } |
@@ -17,2 +17,4 @@ /* | ||
const BROADCAST_CHANNEL_NAME = "msal.broadcast.event"; | ||
export class EventHandler { | ||
@@ -25,2 +27,3 @@ // Callback for subscribing to events | ||
private logger: Logger; | ||
private broadcastChannel: BroadcastChannel; | ||
@@ -30,2 +33,4 @@ constructor(logger?: Logger) { | ||
this.logger = logger || new Logger({}); | ||
this.broadcastChannel = new BroadcastChannel(BROADCAST_CHANNEL_NAME); | ||
this.invokeCrossTabCallbacks = this.invokeCrossTabCallbacks.bind(this); | ||
} | ||
@@ -83,32 +88,78 @@ | ||
): void { | ||
if (typeof window !== "undefined") { | ||
const message: EventMessage = { | ||
eventType: eventType, | ||
interactionType: interactionType || null, | ||
payload: payload || null, | ||
error: error || null, | ||
timestamp: Date.now(), | ||
}; | ||
const message: EventMessage = { | ||
eventType: eventType, | ||
interactionType: interactionType || null, | ||
payload: payload || null, | ||
error: error || null, | ||
timestamp: Date.now(), | ||
}; | ||
this.eventCallbacks.forEach( | ||
( | ||
[callback, eventTypes]: [ | ||
EventCallbackFunction, | ||
Array<EventType> | ||
], | ||
callbackId: string | ||
) => { | ||
if ( | ||
eventTypes.length === 0 || | ||
eventTypes.includes(eventType) | ||
) { | ||
this.logger.verbose( | ||
`Emitting event to callback ${callbackId}: ${eventType}` | ||
); | ||
callback.apply(null, [message]); | ||
} | ||
} | ||
); | ||
switch (eventType) { | ||
case EventType.ACCOUNT_ADDED: | ||
case EventType.ACCOUNT_REMOVED: | ||
case EventType.ACTIVE_ACCOUNT_CHANGED: | ||
// Send event to other open tabs / MSAL instances on same domain | ||
this.broadcastChannel.postMessage(message); | ||
break; | ||
default: | ||
// Emit event to callbacks registered in this instance | ||
this.invokeCallbacks(message); | ||
break; | ||
} | ||
} | ||
/** | ||
* Invoke registered callbacks | ||
* @param message | ||
*/ | ||
private invokeCallbacks(message: EventMessage): void { | ||
this.eventCallbacks.forEach( | ||
( | ||
[callback, eventTypes]: [ | ||
EventCallbackFunction, | ||
Array<EventType> | ||
], | ||
callbackId: string | ||
) => { | ||
if ( | ||
eventTypes.length === 0 || | ||
eventTypes.includes(message.eventType) | ||
) { | ||
this.logger.verbose( | ||
`Emitting event to callback ${callbackId}: ${message.eventType}` | ||
); | ||
callback.apply(null, [message]); | ||
} | ||
} | ||
); | ||
} | ||
/** | ||
* Wrapper around invokeCallbacks to handle broadcast events received from other tabs/instances | ||
* @param event | ||
*/ | ||
private invokeCrossTabCallbacks(event: MessageEvent): void { | ||
const message = event.data as EventMessage; | ||
this.invokeCallbacks(message); | ||
} | ||
/** | ||
* Listen for events broadcasted from other tabs/instances | ||
*/ | ||
subscribeCrossTab(): void { | ||
this.broadcastChannel.addEventListener( | ||
"message", | ||
this.invokeCrossTabCallbacks | ||
); | ||
} | ||
/** | ||
* Unsubscribe from broadcast events | ||
*/ | ||
unsubscribeCrossTab(): void { | ||
this.broadcastChannel.removeEventListener( | ||
"message", | ||
this.invokeCrossTabCallbacks | ||
); | ||
} | ||
} |
/* eslint-disable header/header */ | ||
export const name = "@azure/msal-browser"; | ||
export const version = "4.1.0"; | ||
export const version = "4.2.0"; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
6180198
78543
131
5
+ Added@azure/msal-common@15.1.1(transitive)
- Removed@azure/msal-common@15.1.0(transitive)
Updated@azure/msal-common@15.1.1