@azure/msal-browser 3.24.0 → 3.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/app/IPublicClientApplication.d.ts +2 -1
- package/dist/app/IPublicClientApplication.d.ts.map +1 -1
- package/dist/app/IPublicClientApplication.mjs +1 -1
- package/dist/app/IPublicClientApplication.mjs.map +1 -1
- package/dist/app/PublicClientApplication.d.ts +3 -1
- package/dist/app/PublicClientApplication.d.ts.map +1 -1
- package/dist/app/PublicClientApplication.mjs +4 -3
- package/dist/app/PublicClientApplication.mjs.map +1 -1
- package/dist/app/PublicClientNext.d.ts +2 -1
- package/dist/app/PublicClientNext.d.ts.map +1 -1
- package/dist/app/PublicClientNext.mjs +3 -3
- package/dist/app/PublicClientNext.mjs.map +1 -1
- package/dist/broker/nativeBroker/NativeMessageHandler.mjs +1 -1
- package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
- package/dist/cache/AccountManager.mjs +1 -1
- package/dist/cache/AsyncMemoryStorage.mjs +1 -1
- package/dist/cache/BrowserCacheManager.mjs +1 -1
- package/dist/cache/BrowserStorage.mjs +1 -1
- package/dist/cache/DatabaseStorage.mjs +1 -1
- package/dist/cache/MemoryStorage.mjs +1 -1
- package/dist/cache/TokenCache.mjs +1 -1
- package/dist/config/Configuration.mjs +1 -1
- package/dist/controllers/ControllerFactory.mjs +1 -1
- package/dist/controllers/IController.d.ts +2 -4
- package/dist/controllers/IController.d.ts.map +1 -1
- package/dist/controllers/NestedAppAuthController.d.ts +3 -6
- package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
- package/dist/controllers/NestedAppAuthController.mjs +5 -11
- package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
- package/dist/controllers/StandardController.d.ts +7 -5
- package/dist/controllers/StandardController.d.ts.map +1 -1
- package/dist/controllers/StandardController.mjs +78 -14
- package/dist/controllers/StandardController.mjs.map +1 -1
- package/dist/controllers/UnknownOperatingContextController.d.ts +2 -4
- package/dist/controllers/UnknownOperatingContextController.d.ts.map +1 -1
- package/dist/controllers/UnknownOperatingContextController.mjs +10 -11
- package/dist/controllers/UnknownOperatingContextController.mjs.map +1 -1
- package/dist/crypto/BrowserCrypto.mjs +1 -1
- package/dist/crypto/CryptoOps.mjs +1 -1
- package/dist/crypto/PkceGenerator.mjs +1 -1
- package/dist/crypto/SignedHttpRequest.mjs +1 -1
- package/dist/encode/Base64Decode.mjs +1 -1
- package/dist/encode/Base64Encode.mjs +1 -1
- package/dist/error/BrowserAuthError.mjs +1 -1
- package/dist/error/BrowserAuthErrorCodes.mjs +1 -1
- package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
- package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
- package/dist/error/NativeAuthError.mjs +1 -1
- package/dist/error/NativeAuthErrorCodes.mjs +1 -1
- package/dist/error/NestedAppAuthError.mjs +1 -1
- package/dist/event/EventHandler.d.ts +6 -18
- package/dist/event/EventHandler.d.ts.map +1 -1
- package/dist/event/EventHandler.mjs +23 -87
- package/dist/event/EventHandler.mjs.map +1 -1
- package/dist/event/EventMessage.mjs +1 -1
- package/dist/event/EventType.mjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
- package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
- package/dist/interaction_client/NativeInteractionClient.mjs +1 -1
- package/dist/interaction_client/PopupClient.mjs +1 -1
- package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
- package/dist/interaction_client/RedirectClient.mjs +20 -2
- package/dist/interaction_client/RedirectClient.mjs.map +1 -1
- package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
- package/dist/interaction_client/SilentCacheClient.mjs +1 -1
- package/dist/interaction_client/SilentIframeClient.mjs +1 -1
- package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
- package/dist/interaction_client/StandardInteractionClient.mjs +1 -1
- package/dist/interaction_handler/InteractionHandler.mjs +1 -1
- package/dist/interaction_handler/RedirectHandler.mjs +1 -1
- package/dist/interaction_handler/SilentHandler.mjs +1 -1
- package/dist/naa/BridgeError.mjs +1 -1
- package/dist/naa/BridgeProxy.mjs +1 -1
- package/dist/naa/BridgeStatusCode.mjs +1 -1
- package/dist/naa/mapping/NestedAppAuthAdapter.mjs +1 -1
- package/dist/navigation/NavigationClient.mjs +1 -1
- package/dist/network/FetchClient.mjs +1 -1
- package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
- package/dist/operatingcontext/NestedAppOperatingContext.mjs +1 -1
- package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
- package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
- package/dist/packageMetadata.d.ts +1 -1
- package/dist/packageMetadata.mjs +2 -2
- package/dist/request/RequestHelpers.mjs +1 -1
- package/dist/response/ResponseHandler.mjs +1 -1
- package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
- package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
- package/dist/utils/BrowserConstants.mjs +1 -1
- package/dist/utils/BrowserProtocolUtils.mjs +1 -1
- package/dist/utils/BrowserUtils.mjs +1 -1
- package/lib/msal-browser.cjs +198 -183
- package/lib/msal-browser.cjs.map +1 -1
- package/lib/msal-browser.js +198 -183
- package/lib/msal-browser.js.map +1 -1
- package/lib/msal-browser.min.js +61 -61
- package/lib/types/app/IPublicClientApplication.d.ts +2 -1
- package/lib/types/app/IPublicClientApplication.d.ts.map +1 -1
- package/lib/types/app/PublicClientApplication.d.ts +3 -1
- package/lib/types/app/PublicClientApplication.d.ts.map +1 -1
- package/lib/types/app/PublicClientNext.d.ts +2 -1
- package/lib/types/app/PublicClientNext.d.ts.map +1 -1
- package/lib/types/controllers/IController.d.ts +2 -4
- package/lib/types/controllers/IController.d.ts.map +1 -1
- package/lib/types/controllers/NestedAppAuthController.d.ts +3 -6
- package/lib/types/controllers/NestedAppAuthController.d.ts.map +1 -1
- package/lib/types/controllers/StandardController.d.ts +7 -5
- package/lib/types/controllers/StandardController.d.ts.map +1 -1
- package/lib/types/controllers/UnknownOperatingContextController.d.ts +2 -4
- package/lib/types/controllers/UnknownOperatingContextController.d.ts.map +1 -1
- package/lib/types/event/EventHandler.d.ts +6 -18
- package/lib/types/event/EventHandler.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/interaction_client/RedirectClient.d.ts.map +1 -1
- package/lib/types/packageMetadata.d.ts +1 -1
- package/package.json +2 -4
- package/src/app/IPublicClientApplication.ts +5 -1
- package/src/app/PublicClientApplication.ts +7 -2
- package/src/app/PublicClientNext.ts +6 -2
- package/src/controllers/IController.ts +5 -5
- package/src/controllers/NestedAppAuthController.ts +7 -11
- package/src/controllers/StandardController.ts +105 -13
- package/src/controllers/UnknownOperatingContextController.ts +12 -14
- package/src/event/EventHandler.ts +42 -117
- package/src/index.ts +1 -0
- package/src/interaction_client/RedirectClient.ts +25 -1
- package/src/packageMetadata.ts +1 -1
|
@@ -118,7 +118,7 @@ export class NestedAppAuthController implements IController {
|
|
|
118
118
|
this.logger
|
|
119
119
|
);
|
|
120
120
|
|
|
121
|
-
this.eventHandler = new EventHandler(this.logger
|
|
121
|
+
this.eventHandler = new EventHandler(this.logger);
|
|
122
122
|
|
|
123
123
|
this.nestedAppAuthAdapter = new NestedAppAuthAdapter(
|
|
124
124
|
this.config.auth.clientId,
|
|
@@ -140,14 +140,6 @@ export class NestedAppAuthController implements IController {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
/**
|
|
144
|
-
* Returns the event handler instance
|
|
145
|
-
* @returns EventHandler
|
|
146
|
-
*/
|
|
147
|
-
getEventHandler(): EventHandler {
|
|
148
|
-
return this.eventHandler;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
143
|
/**
|
|
152
144
|
* Factory function to create a new instance of NestedAppAuthController
|
|
153
145
|
* @param operatingContext
|
|
@@ -588,9 +580,13 @@ export class NestedAppAuthController implements IController {
|
|
|
588
580
|
/**
|
|
589
581
|
* Adds event callbacks to array
|
|
590
582
|
* @param callback
|
|
583
|
+
* @param eventTypes
|
|
591
584
|
*/
|
|
592
|
-
addEventCallback(
|
|
593
|
-
|
|
585
|
+
addEventCallback(
|
|
586
|
+
callback: EventCallbackFunction,
|
|
587
|
+
eventTypes?: Array<EventType>
|
|
588
|
+
): string | null {
|
|
589
|
+
return this.eventHandler.addEventCallback(callback, eventTypes);
|
|
594
590
|
}
|
|
595
591
|
|
|
596
592
|
/**
|
|
@@ -28,6 +28,8 @@ import {
|
|
|
28
28
|
AccountFilter,
|
|
29
29
|
buildStaticAuthorityOptions,
|
|
30
30
|
InteractionRequiredAuthErrorCodes,
|
|
31
|
+
PersistentCacheKeys,
|
|
32
|
+
CacheManager,
|
|
31
33
|
} from "@azure/msal-common/browser";
|
|
32
34
|
import {
|
|
33
35
|
BrowserCacheManager,
|
|
@@ -176,6 +178,9 @@ export class StandardController implements IController {
|
|
|
176
178
|
|
|
177
179
|
private ssoSilentMeasurement?: InProgressPerformanceEvent;
|
|
178
180
|
private acquireTokenByCodeAsyncMeasurement?: InProgressPerformanceEvent;
|
|
181
|
+
|
|
182
|
+
// Flag which indicates if we're currently listening for account storage events
|
|
183
|
+
private listeningToStorageEvents: boolean;
|
|
179
184
|
/**
|
|
180
185
|
* @constructor
|
|
181
186
|
* Constructor for the PublicClientApplication used to instantiate the PublicClientApplication object
|
|
@@ -228,7 +233,7 @@ export class StandardController implements IController {
|
|
|
228
233
|
? new CryptoOps(this.logger, this.performanceClient)
|
|
229
234
|
: DEFAULT_CRYPTO_IMPLEMENTATION;
|
|
230
235
|
|
|
231
|
-
this.eventHandler = new EventHandler(this.logger
|
|
236
|
+
this.eventHandler = new EventHandler(this.logger);
|
|
232
237
|
|
|
233
238
|
// Initialize the browser storage class.
|
|
234
239
|
this.browserStorage = this.isBrowserEnvironment
|
|
@@ -279,6 +284,11 @@ export class StandardController implements IController {
|
|
|
279
284
|
// Register listener functions
|
|
280
285
|
this.trackPageVisibilityWithMeasurement =
|
|
281
286
|
this.trackPageVisibilityWithMeasurement.bind(this);
|
|
287
|
+
|
|
288
|
+
// account storage events
|
|
289
|
+
this.listeningToStorageEvents = false;
|
|
290
|
+
this.handleAccountCacheChange =
|
|
291
|
+
this.handleAccountCacheChange.bind(this);
|
|
282
292
|
}
|
|
283
293
|
|
|
284
294
|
static async createController(
|
|
@@ -314,6 +324,13 @@ export class StandardController implements IController {
|
|
|
314
324
|
return;
|
|
315
325
|
}
|
|
316
326
|
|
|
327
|
+
if (!this.isBrowserEnvironment) {
|
|
328
|
+
this.logger.info("in non-browser environment, exiting early.");
|
|
329
|
+
this.initialized = true;
|
|
330
|
+
this.eventHandler.emitEvent(EventType.INITIALIZE_END);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
317
334
|
const initCorrelationId =
|
|
318
335
|
request?.correlationId || this.getRequestCorrelationId();
|
|
319
336
|
const allowNativeBroker = this.config.system.allowNativeBroker;
|
|
@@ -354,7 +371,6 @@ export class StandardController implements IController {
|
|
|
354
371
|
|
|
355
372
|
this.initialized = true;
|
|
356
373
|
this.eventHandler.emitEvent(EventType.INITIALIZE_END);
|
|
357
|
-
|
|
358
374
|
initMeasurement.end({ allowNativeBroker, success: true });
|
|
359
375
|
}
|
|
360
376
|
|
|
@@ -1336,6 +1352,10 @@ export class StandardController implements IController {
|
|
|
1336
1352
|
* @param logoutRequest
|
|
1337
1353
|
*/
|
|
1338
1354
|
async clearCache(logoutRequest?: ClearCacheRequest): Promise<void> {
|
|
1355
|
+
if (!this.isBrowserEnvironment) {
|
|
1356
|
+
this.logger.info("in non-browser environment, returning early.");
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1339
1359
|
const correlationId = this.getRequestCorrelationId(logoutRequest);
|
|
1340
1360
|
const cacheClient = this.createSilentCacheClient(correlationId);
|
|
1341
1361
|
return cacheClient.logout(logoutRequest);
|
|
@@ -1697,8 +1717,11 @@ export class StandardController implements IController {
|
|
|
1697
1717
|
* Adds event callbacks to array
|
|
1698
1718
|
* @param callback
|
|
1699
1719
|
*/
|
|
1700
|
-
addEventCallback(
|
|
1701
|
-
|
|
1720
|
+
addEventCallback(
|
|
1721
|
+
callback: EventCallbackFunction,
|
|
1722
|
+
eventTypes?: Array<EventType>
|
|
1723
|
+
): string | null {
|
|
1724
|
+
return this.eventHandler.addEventCallback(callback, eventTypes);
|
|
1702
1725
|
}
|
|
1703
1726
|
|
|
1704
1727
|
/**
|
|
@@ -1716,6 +1739,7 @@ export class StandardController implements IController {
|
|
|
1716
1739
|
* @returns {string}
|
|
1717
1740
|
*/
|
|
1718
1741
|
addPerformanceCallback(callback: PerformanceCallbackFunction): string {
|
|
1742
|
+
BrowserUtils.blockNonBrowserEnvironment();
|
|
1719
1743
|
return this.performanceClient.addPerformanceCallback(callback);
|
|
1720
1744
|
}
|
|
1721
1745
|
|
|
@@ -1733,14 +1757,89 @@ export class StandardController implements IController {
|
|
|
1733
1757
|
* Adds event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window
|
|
1734
1758
|
*/
|
|
1735
1759
|
enableAccountStorageEvents(): void {
|
|
1736
|
-
|
|
1760
|
+
if (typeof window === "undefined") {
|
|
1761
|
+
return;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
if (!this.listeningToStorageEvents) {
|
|
1765
|
+
this.logger.verbose("Adding account storage listener.");
|
|
1766
|
+
this.listeningToStorageEvents = true;
|
|
1767
|
+
window.addEventListener("storage", this.handleAccountCacheChange);
|
|
1768
|
+
} else {
|
|
1769
|
+
this.logger.verbose("Account storage listener already registered.");
|
|
1770
|
+
}
|
|
1737
1771
|
}
|
|
1738
1772
|
|
|
1739
1773
|
/**
|
|
1740
1774
|
* Removes event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window
|
|
1741
1775
|
*/
|
|
1742
1776
|
disableAccountStorageEvents(): void {
|
|
1743
|
-
|
|
1777
|
+
if (typeof window === "undefined") {
|
|
1778
|
+
return;
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
if (this.listeningToStorageEvents) {
|
|
1782
|
+
this.logger.verbose("Removing account storage listener.");
|
|
1783
|
+
window.removeEventListener(
|
|
1784
|
+
"storage",
|
|
1785
|
+
this.handleAccountCacheChange
|
|
1786
|
+
);
|
|
1787
|
+
this.listeningToStorageEvents = false;
|
|
1788
|
+
} else {
|
|
1789
|
+
this.logger.verbose("No account storage listener registered.");
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
/**
|
|
1794
|
+
* Emit account added/removed events when cached accounts are changed in a different tab or frame
|
|
1795
|
+
*/
|
|
1796
|
+
protected handleAccountCacheChange(e: StorageEvent): void {
|
|
1797
|
+
try {
|
|
1798
|
+
// Handle active account filter change
|
|
1799
|
+
if (e.key?.includes(PersistentCacheKeys.ACTIVE_ACCOUNT_FILTERS)) {
|
|
1800
|
+
// This event has no payload, it only signals cross-tab app instances that the results of calling getActiveAccount() will have changed
|
|
1801
|
+
this.eventHandler.emitEvent(EventType.ACTIVE_ACCOUNT_CHANGED);
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
// Handle account object change
|
|
1805
|
+
const cacheValue = e.newValue || e.oldValue;
|
|
1806
|
+
if (!cacheValue) {
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
const parsedValue = JSON.parse(cacheValue);
|
|
1810
|
+
if (
|
|
1811
|
+
typeof parsedValue !== "object" ||
|
|
1812
|
+
!AccountEntity.isAccountEntity(parsedValue)
|
|
1813
|
+
) {
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
const accountEntity = CacheManager.toObject<AccountEntity>(
|
|
1817
|
+
new AccountEntity(),
|
|
1818
|
+
parsedValue
|
|
1819
|
+
);
|
|
1820
|
+
const accountInfo = accountEntity.getAccountInfo();
|
|
1821
|
+
if (!e.oldValue && e.newValue) {
|
|
1822
|
+
this.logger.info(
|
|
1823
|
+
"Account was added to cache in a different window"
|
|
1824
|
+
);
|
|
1825
|
+
this.eventHandler.emitEvent(
|
|
1826
|
+
EventType.ACCOUNT_ADDED,
|
|
1827
|
+
undefined,
|
|
1828
|
+
accountInfo
|
|
1829
|
+
);
|
|
1830
|
+
} else if (!e.newValue && e.oldValue) {
|
|
1831
|
+
this.logger.info(
|
|
1832
|
+
"Account was removed from cache in a different window"
|
|
1833
|
+
);
|
|
1834
|
+
this.eventHandler.emitEvent(
|
|
1835
|
+
EventType.ACCOUNT_REMOVED,
|
|
1836
|
+
undefined,
|
|
1837
|
+
accountInfo
|
|
1838
|
+
);
|
|
1839
|
+
}
|
|
1840
|
+
} catch (e) {
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1744
1843
|
}
|
|
1745
1844
|
|
|
1746
1845
|
/**
|
|
@@ -1804,13 +1903,6 @@ export class StandardController implements IController {
|
|
|
1804
1903
|
return this.isBrowserEnvironment;
|
|
1805
1904
|
}
|
|
1806
1905
|
|
|
1807
|
-
/**
|
|
1808
|
-
* Returns the event handler
|
|
1809
|
-
*/
|
|
1810
|
-
getEventHandler(): EventHandler {
|
|
1811
|
-
return this.eventHandler;
|
|
1812
|
-
}
|
|
1813
|
-
|
|
1814
1906
|
/**
|
|
1815
1907
|
* Generates a correlation id for a request if none is provided.
|
|
1816
1908
|
*
|
|
@@ -37,9 +37,9 @@ import {
|
|
|
37
37
|
blockAPICallsBeforeInitialize,
|
|
38
38
|
blockNonBrowserEnvironment,
|
|
39
39
|
} from "../utils/BrowserUtils.js";
|
|
40
|
-
import { EventHandler } from "../event/EventHandler.js";
|
|
41
40
|
import { EventCallbackFunction } from "../event/EventMessage.js";
|
|
42
41
|
import { ClearCacheRequest } from "../request/ClearCacheRequest.js";
|
|
42
|
+
import { EventType } from "../event/EventType.js";
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* UnknownOperatingContextController class
|
|
@@ -80,8 +80,6 @@ export class UnknownOperatingContextController implements IController {
|
|
|
80
80
|
// Flag representing whether or not the initialize API has been called and completed
|
|
81
81
|
protected initialized: boolean = false;
|
|
82
82
|
|
|
83
|
-
protected readonly eventHandler: EventHandler;
|
|
84
|
-
|
|
85
83
|
constructor(operatingContext: UnknownOperatingContext) {
|
|
86
84
|
this.operatingContext = operatingContext;
|
|
87
85
|
|
|
@@ -114,17 +112,11 @@ export class UnknownOperatingContextController implements IController {
|
|
|
114
112
|
this.config.auth.clientId,
|
|
115
113
|
this.logger
|
|
116
114
|
);
|
|
117
|
-
|
|
118
|
-
this.eventHandler = new EventHandler(this.logger, this.browserCrypto);
|
|
119
115
|
}
|
|
120
116
|
getBrowserStorage(): BrowserCacheManager {
|
|
121
117
|
return this.browserStorage;
|
|
122
118
|
}
|
|
123
119
|
|
|
124
|
-
getEventHandler(): EventHandler {
|
|
125
|
-
return this.eventHandler;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
120
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
129
121
|
getAccount(accountFilter: AccountFilter): AccountInfo | null {
|
|
130
122
|
return null;
|
|
@@ -210,12 +202,18 @@ export class UnknownOperatingContextController implements IController {
|
|
|
210
202
|
blockNonBrowserEnvironment();
|
|
211
203
|
return {} as Promise<AuthenticationResult>;
|
|
212
204
|
}
|
|
213
|
-
addEventCallback(
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
205
|
+
addEventCallback(
|
|
206
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
207
|
+
callback: EventCallbackFunction,
|
|
208
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
209
|
+
eventTypes?: Array<EventType>
|
|
210
|
+
): string | null {
|
|
211
|
+
return null;
|
|
218
212
|
}
|
|
213
|
+
removeEventCallback(
|
|
214
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
215
|
+
callbackId: string
|
|
216
|
+
): void {}
|
|
219
217
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
220
218
|
addPerformanceCallback(callback: PerformanceCallbackFunction): string {
|
|
221
219
|
blockAPICallsBeforeInitialize(this.initialized);
|
|
@@ -3,13 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
ICrypto,
|
|
8
|
-
Logger,
|
|
9
|
-
AccountEntity,
|
|
10
|
-
CacheManager,
|
|
11
|
-
PersistentCacheKeys,
|
|
12
|
-
} from "@azure/msal-common/browser";
|
|
6
|
+
import { Logger } from "@azure/msal-common/browser";
|
|
13
7
|
import { InteractionType } from "../utils/BrowserConstants.js";
|
|
14
8
|
import {
|
|
15
9
|
EventCallbackFunction,
|
|
@@ -18,37 +12,44 @@ import {
|
|
|
18
12
|
EventPayload,
|
|
19
13
|
} from "./EventMessage.js";
|
|
20
14
|
import { EventType } from "./EventType.js";
|
|
21
|
-
import {
|
|
15
|
+
import { createGuid } from "../utils/BrowserUtils.js";
|
|
22
16
|
|
|
23
17
|
export class EventHandler {
|
|
24
18
|
// Callback for subscribing to events
|
|
25
|
-
private eventCallbacks: Map<
|
|
19
|
+
private eventCallbacks: Map<
|
|
20
|
+
string,
|
|
21
|
+
[EventCallbackFunction, Array<EventType>]
|
|
22
|
+
>;
|
|
26
23
|
private logger: Logger;
|
|
27
|
-
private browserCrypto: ICrypto;
|
|
28
|
-
private listeningToStorageEvents: boolean;
|
|
29
24
|
|
|
30
|
-
constructor(logger
|
|
25
|
+
constructor(logger?: Logger) {
|
|
31
26
|
this.eventCallbacks = new Map();
|
|
32
|
-
this.logger = logger;
|
|
33
|
-
this.browserCrypto = browserCrypto;
|
|
34
|
-
this.listeningToStorageEvents = false;
|
|
35
|
-
this.handleAccountCacheChange =
|
|
36
|
-
this.handleAccountCacheChange.bind(this);
|
|
27
|
+
this.logger = logger || new Logger({});
|
|
37
28
|
}
|
|
38
29
|
|
|
39
30
|
/**
|
|
40
31
|
* Adds event callbacks to array
|
|
41
|
-
* @param callback
|
|
32
|
+
* @param callback - callback to be invoked when an event is raised
|
|
33
|
+
* @param eventTypes - list of events that this callback will be invoked for, if not provided callback will be invoked for all events
|
|
34
|
+
* @param callbackId - Identifier for the callback, used to locate and remove the callback when no longer required
|
|
42
35
|
*/
|
|
43
|
-
addEventCallback(
|
|
36
|
+
addEventCallback(
|
|
37
|
+
callback: EventCallbackFunction,
|
|
38
|
+
eventTypes?: Array<EventType>,
|
|
39
|
+
callbackId?: string
|
|
40
|
+
): string | null {
|
|
44
41
|
if (typeof window !== "undefined") {
|
|
45
|
-
const
|
|
46
|
-
this.eventCallbacks.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
const id = callbackId || createGuid();
|
|
43
|
+
if (this.eventCallbacks.has(id)) {
|
|
44
|
+
this.logger.error(
|
|
45
|
+
`Event callback with id: ${id} is already registered. Please provide a unique id or remove the existing callback and try again.`
|
|
46
|
+
);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
this.eventCallbacks.set(id, [callback, eventTypes || []]);
|
|
50
|
+
this.logger.verbose(`Event callback registered with id: ${id}`);
|
|
50
51
|
|
|
51
|
-
return
|
|
52
|
+
return id;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
return null;
|
|
@@ -63,43 +64,6 @@ export class EventHandler {
|
|
|
63
64
|
this.logger.verbose(`Event callback ${callbackId} removed.`);
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
/**
|
|
67
|
-
* Adds event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window
|
|
68
|
-
*/
|
|
69
|
-
enableAccountStorageEvents(): void {
|
|
70
|
-
if (typeof window === "undefined") {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (!this.listeningToStorageEvents) {
|
|
75
|
-
this.logger.verbose("Adding account storage listener.");
|
|
76
|
-
this.listeningToStorageEvents = true;
|
|
77
|
-
window.addEventListener("storage", this.handleAccountCacheChange);
|
|
78
|
-
} else {
|
|
79
|
-
this.logger.verbose("Account storage listener already registered.");
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Removes event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window
|
|
85
|
-
*/
|
|
86
|
-
disableAccountStorageEvents(): void {
|
|
87
|
-
if (typeof window === "undefined") {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (this.listeningToStorageEvents) {
|
|
92
|
-
this.logger.verbose("Removing account storage listener.");
|
|
93
|
-
window.removeEventListener(
|
|
94
|
-
"storage",
|
|
95
|
-
this.handleAccountCacheChange
|
|
96
|
-
);
|
|
97
|
-
this.listeningToStorageEvents = false;
|
|
98
|
-
} else {
|
|
99
|
-
this.logger.verbose("No account storage listener registered.");
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
67
|
/**
|
|
104
68
|
* Emits events by calling callback with event message
|
|
105
69
|
* @param eventType
|
|
@@ -122,64 +86,25 @@ export class EventHandler {
|
|
|
122
86
|
timestamp: Date.now(),
|
|
123
87
|
};
|
|
124
88
|
|
|
125
|
-
this.logger.info(`Emitting event: ${eventType}`);
|
|
126
|
-
|
|
127
89
|
this.eventCallbacks.forEach(
|
|
128
|
-
(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
90
|
+
(
|
|
91
|
+
[callback, eventTypes]: [
|
|
92
|
+
EventCallbackFunction,
|
|
93
|
+
Array<EventType>
|
|
94
|
+
],
|
|
95
|
+
callbackId: string
|
|
96
|
+
) => {
|
|
97
|
+
if (
|
|
98
|
+
eventTypes.length === 0 ||
|
|
99
|
+
eventTypes.includes(eventType)
|
|
100
|
+
) {
|
|
101
|
+
this.logger.verbose(
|
|
102
|
+
`Emitting event to callback ${callbackId}: ${eventType}`
|
|
103
|
+
);
|
|
104
|
+
callback.apply(null, [message]);
|
|
105
|
+
}
|
|
133
106
|
}
|
|
134
107
|
);
|
|
135
108
|
}
|
|
136
109
|
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Emit account added/removed events when cached accounts are changed in a different tab or frame
|
|
140
|
-
*/
|
|
141
|
-
private handleAccountCacheChange(e: StorageEvent): void {
|
|
142
|
-
try {
|
|
143
|
-
// Handle active account filter change
|
|
144
|
-
if (e.key?.includes(PersistentCacheKeys.ACTIVE_ACCOUNT_FILTERS)) {
|
|
145
|
-
// This event has no payload, it only signals cross-tab app instances that the results of calling getActiveAccount() will have changed
|
|
146
|
-
this.emitEvent(EventType.ACTIVE_ACCOUNT_CHANGED);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Handle account object change
|
|
150
|
-
const cacheValue = e.newValue || e.oldValue;
|
|
151
|
-
if (!cacheValue) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
const parsedValue = JSON.parse(cacheValue);
|
|
155
|
-
if (
|
|
156
|
-
typeof parsedValue !== "object" ||
|
|
157
|
-
!AccountEntity.isAccountEntity(parsedValue)
|
|
158
|
-
) {
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
const accountEntity = CacheManager.toObject<AccountEntity>(
|
|
162
|
-
new AccountEntity(),
|
|
163
|
-
parsedValue
|
|
164
|
-
);
|
|
165
|
-
const accountInfo = accountEntity.getAccountInfo();
|
|
166
|
-
if (!e.oldValue && e.newValue) {
|
|
167
|
-
this.logger.info(
|
|
168
|
-
"Account was added to cache in a different window"
|
|
169
|
-
);
|
|
170
|
-
this.emitEvent(EventType.ACCOUNT_ADDED, undefined, accountInfo);
|
|
171
|
-
} else if (!e.newValue && e.oldValue) {
|
|
172
|
-
this.logger.info(
|
|
173
|
-
"Account was removed from cache in a different window"
|
|
174
|
-
);
|
|
175
|
-
this.emitEvent(
|
|
176
|
-
EventType.ACCOUNT_REMOVED,
|
|
177
|
-
undefined,
|
|
178
|
-
accountInfo
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
} catch (e) {
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
110
|
}
|
package/src/index.ts
CHANGED
|
@@ -49,6 +49,22 @@ import { EventError } from "../event/EventMessage.js";
|
|
|
49
49
|
import { AuthenticationResult } from "../response/AuthenticationResult.js";
|
|
50
50
|
import * as ResponseHandler from "../response/ResponseHandler.js";
|
|
51
51
|
|
|
52
|
+
function getNavigationType(): NavigationTimingType | undefined {
|
|
53
|
+
if (
|
|
54
|
+
typeof window === "undefined" ||
|
|
55
|
+
typeof window.performance === "undefined" ||
|
|
56
|
+
typeof window.performance.getEntriesByType !== "function"
|
|
57
|
+
) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const navigationEntries = window.performance.getEntriesByType("navigation");
|
|
62
|
+
const navigation = navigationEntries.length
|
|
63
|
+
? (navigationEntries[0] as PerformanceNavigationTiming)
|
|
64
|
+
: undefined;
|
|
65
|
+
return navigation?.type;
|
|
66
|
+
}
|
|
67
|
+
|
|
52
68
|
export class RedirectClient extends StandardInteractionClient {
|
|
53
69
|
protected nativeStorage: BrowserCacheManager;
|
|
54
70
|
|
|
@@ -223,7 +239,15 @@ export class RedirectClient extends StandardInteractionClient {
|
|
|
223
239
|
this.browserStorage.cleanRequestByInteractionType(
|
|
224
240
|
InteractionType.Redirect
|
|
225
241
|
);
|
|
226
|
-
|
|
242
|
+
|
|
243
|
+
// Do not instrument "no_server_response" if user clicked back button
|
|
244
|
+
if (getNavigationType() !== "back_forward") {
|
|
245
|
+
parentMeasurement.event.errorCode = "no_server_response";
|
|
246
|
+
} else {
|
|
247
|
+
this.logger.verbose(
|
|
248
|
+
"Back navigation event detected. Muting no_server_response error"
|
|
249
|
+
);
|
|
250
|
+
}
|
|
227
251
|
return null;
|
|
228
252
|
}
|
|
229
253
|
|
package/src/packageMetadata.ts
CHANGED