@azure/msal-browser 3.25.0 → 3.26.1
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/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 +26 -18
- 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.mjs +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 +199 -188
- package/lib/msal-browser.cjs.map +1 -1
- package/lib/msal-browser.js +199 -188
- 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/packageMetadata.d.ts +1 -1
- package/package.json +1 -1
- 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 +32 -23
- 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/packageMetadata.ts +1 -1
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
WrapperSKU,
|
|
36
36
|
InteractionType,
|
|
37
37
|
DEFAULT_REQUEST,
|
|
38
|
+
CacheLookupPolicy,
|
|
38
39
|
} from "../utils/BrowserConstants.js";
|
|
39
40
|
import { IController } from "./IController.js";
|
|
40
41
|
import { NestedAppOperatingContext } from "../operatingcontext/NestedAppOperatingContext.js";
|
|
@@ -118,7 +119,7 @@ export class NestedAppAuthController implements IController {
|
|
|
118
119
|
this.logger
|
|
119
120
|
);
|
|
120
121
|
|
|
121
|
-
this.eventHandler = new EventHandler(this.logger
|
|
122
|
+
this.eventHandler = new EventHandler(this.logger);
|
|
122
123
|
|
|
123
124
|
this.nestedAppAuthAdapter = new NestedAppAuthAdapter(
|
|
124
125
|
this.config.auth.clientId,
|
|
@@ -140,14 +141,6 @@ export class NestedAppAuthController implements IController {
|
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
/**
|
|
144
|
-
* Returns the event handler instance
|
|
145
|
-
* @returns EventHandler
|
|
146
|
-
*/
|
|
147
|
-
getEventHandler(): EventHandler {
|
|
148
|
-
return this.eventHandler;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
144
|
/**
|
|
152
145
|
* Factory function to create a new instance of NestedAppAuthController
|
|
153
146
|
* @param operatingContext
|
|
@@ -220,12 +213,13 @@ export class NestedAppAuthController implements IController {
|
|
|
220
213
|
const response = await this.bridgeProxy.getTokenInteractive(
|
|
221
214
|
naaRequest
|
|
222
215
|
);
|
|
223
|
-
const result: AuthenticationResult =
|
|
224
|
-
this.nestedAppAuthAdapter.fromNaaTokenResponse(
|
|
216
|
+
const result: AuthenticationResult = {
|
|
217
|
+
...this.nestedAppAuthAdapter.fromNaaTokenResponse(
|
|
225
218
|
naaRequest,
|
|
226
219
|
response,
|
|
227
220
|
reqTimestamp
|
|
228
|
-
)
|
|
221
|
+
),
|
|
222
|
+
};
|
|
229
223
|
|
|
230
224
|
// cache the tokens in the response
|
|
231
225
|
await this.hydrateCache(result, request);
|
|
@@ -285,7 +279,6 @@ export class NestedAppAuthController implements IController {
|
|
|
285
279
|
|
|
286
280
|
// Look for tokens in the cache first
|
|
287
281
|
const result = await this.acquireTokenFromCache(validRequest);
|
|
288
|
-
|
|
289
282
|
if (result) {
|
|
290
283
|
this.eventHandler.emitEvent(
|
|
291
284
|
EventType.ACQUIRE_TOKEN_SUCCESS,
|
|
@@ -375,7 +368,25 @@ export class NestedAppAuthController implements IController {
|
|
|
375
368
|
nestedAppAuthRequest: true,
|
|
376
369
|
});
|
|
377
370
|
|
|
378
|
-
|
|
371
|
+
// if the request has claims, we cannot look up in the cache
|
|
372
|
+
if (request.claims) {
|
|
373
|
+
this.logger.verbose(
|
|
374
|
+
"Claims are present in the request, skipping cache lookup"
|
|
375
|
+
);
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// respect cache lookup policy
|
|
380
|
+
let result: AuthenticationResult | null = null;
|
|
381
|
+
switch (request.cacheLookupPolicy) {
|
|
382
|
+
case CacheLookupPolicy.Default:
|
|
383
|
+
case CacheLookupPolicy.AccessToken:
|
|
384
|
+
case CacheLookupPolicy.AccessTokenAndRefreshToken:
|
|
385
|
+
result = await this.acquireTokenFromCacheInternal(request);
|
|
386
|
+
break;
|
|
387
|
+
default:
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
379
390
|
|
|
380
391
|
if (result) {
|
|
381
392
|
this.eventHandler.emitEvent(
|
|
@@ -466,7 +477,6 @@ export class NestedAppAuthController implements IController {
|
|
|
466
477
|
if (!cachedAccessToken) {
|
|
467
478
|
this.logger.verbose("No cached access token found");
|
|
468
479
|
return Promise.resolve(null);
|
|
469
|
-
// If access token has expired, remove the token from cache and return null
|
|
470
480
|
} else if (
|
|
471
481
|
TimeUtils.wasClockTurnedBack(cachedAccessToken.cachedAt) ||
|
|
472
482
|
TimeUtils.isTokenExpired(
|
|
@@ -474,12 +484,7 @@ export class NestedAppAuthController implements IController {
|
|
|
474
484
|
this.config.system.tokenRenewalOffsetSeconds
|
|
475
485
|
)
|
|
476
486
|
) {
|
|
477
|
-
this.logger.verbose(
|
|
478
|
-
"Cached access token has expired, deleting all related tokens from cache"
|
|
479
|
-
);
|
|
480
|
-
const accountEntity =
|
|
481
|
-
AccountEntity.createFromAccountInfo(currentAccount);
|
|
482
|
-
await this.browserStorage.removeAccountContext(accountEntity);
|
|
487
|
+
this.logger.verbose("Cached access token has expired");
|
|
483
488
|
return Promise.resolve(null);
|
|
484
489
|
}
|
|
485
490
|
|
|
@@ -588,9 +593,13 @@ export class NestedAppAuthController implements IController {
|
|
|
588
593
|
/**
|
|
589
594
|
* Adds event callbacks to array
|
|
590
595
|
* @param callback
|
|
596
|
+
* @param eventTypes
|
|
591
597
|
*/
|
|
592
|
-
addEventCallback(
|
|
593
|
-
|
|
598
|
+
addEventCallback(
|
|
599
|
+
callback: EventCallbackFunction,
|
|
600
|
+
eventTypes?: Array<EventType>
|
|
601
|
+
): string | null {
|
|
602
|
+
return this.eventHandler.addEventCallback(callback, eventTypes);
|
|
594
603
|
}
|
|
595
604
|
|
|
596
605
|
/**
|
|
@@ -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
package/src/packageMetadata.ts
CHANGED