@azure/msal-browser 4.1.0 → 4.2.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.
Files changed (123) hide show
  1. package/dist/app/IPublicClientApplication.mjs +1 -1
  2. package/dist/app/PublicClientApplication.mjs +1 -1
  3. package/dist/app/PublicClientNext.mjs +1 -1
  4. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +1 -1
  5. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  6. package/dist/cache/AccountManager.mjs +1 -1
  7. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  8. package/dist/cache/BrowserCacheManager.d.ts +10 -3
  9. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  10. package/dist/cache/BrowserCacheManager.mjs +32 -6
  11. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  12. package/dist/cache/CacheHelpers.mjs +1 -1
  13. package/dist/cache/CookieStorage.d.ts +6 -1
  14. package/dist/cache/CookieStorage.d.ts.map +1 -1
  15. package/dist/cache/CookieStorage.mjs +10 -5
  16. package/dist/cache/CookieStorage.mjs.map +1 -1
  17. package/dist/cache/DatabaseStorage.mjs +1 -1
  18. package/dist/cache/LocalStorage.d.ts +2 -0
  19. package/dist/cache/LocalStorage.d.ts.map +1 -1
  20. package/dist/cache/LocalStorage.mjs +52 -4
  21. package/dist/cache/LocalStorage.mjs.map +1 -1
  22. package/dist/cache/MemoryStorage.mjs +1 -1
  23. package/dist/cache/SessionStorage.mjs +1 -1
  24. package/dist/cache/TokenCache.mjs +1 -1
  25. package/dist/config/Configuration.d.ts +2 -1
  26. package/dist/config/Configuration.d.ts.map +1 -1
  27. package/dist/config/Configuration.mjs +1 -1
  28. package/dist/config/Configuration.mjs.map +1 -1
  29. package/dist/controllers/ControllerFactory.mjs +1 -1
  30. package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
  31. package/dist/controllers/NestedAppAuthController.mjs +11 -7
  32. package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
  33. package/dist/controllers/StandardController.d.ts +2 -5
  34. package/dist/controllers/StandardController.d.ts.map +1 -1
  35. package/dist/controllers/StandardController.mjs +16 -63
  36. package/dist/controllers/StandardController.mjs.map +1 -1
  37. package/dist/controllers/UnknownOperatingContextController.d.ts +1 -0
  38. package/dist/controllers/UnknownOperatingContextController.d.ts.map +1 -1
  39. package/dist/controllers/UnknownOperatingContextController.mjs +5 -3
  40. package/dist/controllers/UnknownOperatingContextController.mjs.map +1 -1
  41. package/dist/crypto/BrowserCrypto.mjs +1 -1
  42. package/dist/crypto/CryptoOps.mjs +1 -1
  43. package/dist/crypto/PkceGenerator.mjs +1 -1
  44. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  45. package/dist/encode/Base64Decode.mjs +1 -1
  46. package/dist/encode/Base64Encode.mjs +1 -1
  47. package/dist/error/BrowserAuthError.mjs +1 -1
  48. package/dist/error/BrowserAuthErrorCodes.mjs +1 -1
  49. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  50. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  51. package/dist/error/NativeAuthError.mjs +1 -1
  52. package/dist/error/NativeAuthErrorCodes.mjs +1 -1
  53. package/dist/error/NestedAppAuthError.mjs +1 -1
  54. package/dist/event/EventHandler.d.ts +19 -0
  55. package/dist/event/EventHandler.d.ts.map +1 -1
  56. package/dist/event/EventHandler.mjs +56 -16
  57. package/dist/event/EventHandler.mjs.map +1 -1
  58. package/dist/event/EventMessage.mjs +1 -1
  59. package/dist/event/EventType.mjs +1 -1
  60. package/dist/index.mjs +1 -1
  61. package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
  62. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  63. package/dist/interaction_client/NativeInteractionClient.mjs +1 -1
  64. package/dist/interaction_client/PopupClient.mjs +1 -1
  65. package/dist/interaction_client/RedirectClient.mjs +1 -1
  66. package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
  67. package/dist/interaction_client/SilentCacheClient.mjs +1 -1
  68. package/dist/interaction_client/SilentIframeClient.mjs +1 -1
  69. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  70. package/dist/interaction_client/StandardInteractionClient.mjs +1 -1
  71. package/dist/interaction_handler/InteractionHandler.mjs +1 -1
  72. package/dist/interaction_handler/RedirectHandler.mjs +1 -1
  73. package/dist/interaction_handler/SilentHandler.mjs +1 -1
  74. package/dist/naa/BridgeError.mjs +1 -1
  75. package/dist/naa/BridgeProxy.mjs +1 -1
  76. package/dist/naa/BridgeStatusCode.mjs +1 -1
  77. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +1 -1
  78. package/dist/navigation/NavigationClient.mjs +1 -1
  79. package/dist/network/FetchClient.mjs +1 -1
  80. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  81. package/dist/operatingcontext/NestedAppOperatingContext.mjs +1 -1
  82. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  83. package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
  84. package/dist/packageMetadata.d.ts +1 -1
  85. package/dist/packageMetadata.mjs +2 -2
  86. package/dist/request/RequestHelpers.mjs +1 -1
  87. package/dist/response/ResponseHandler.mjs +1 -1
  88. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  89. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  90. package/dist/utils/BrowserConstants.mjs +1 -1
  91. package/dist/utils/BrowserProtocolUtils.mjs +1 -1
  92. package/dist/utils/BrowserUtils.mjs +1 -1
  93. package/lib/msal-browser.cjs +267 -190
  94. package/lib/msal-browser.cjs.map +1 -1
  95. package/lib/msal-browser.js +267 -190
  96. package/lib/msal-browser.js.map +1 -1
  97. package/lib/msal-browser.min.js +63 -63
  98. package/lib/types/cache/BrowserCacheManager.d.ts +10 -3
  99. package/lib/types/cache/BrowserCacheManager.d.ts.map +1 -1
  100. package/lib/types/cache/CookieStorage.d.ts +6 -1
  101. package/lib/types/cache/CookieStorage.d.ts.map +1 -1
  102. package/lib/types/cache/LocalStorage.d.ts +2 -0
  103. package/lib/types/cache/LocalStorage.d.ts.map +1 -1
  104. package/lib/types/config/Configuration.d.ts +2 -1
  105. package/lib/types/config/Configuration.d.ts.map +1 -1
  106. package/lib/types/controllers/NestedAppAuthController.d.ts.map +1 -1
  107. package/lib/types/controllers/StandardController.d.ts +2 -5
  108. package/lib/types/controllers/StandardController.d.ts.map +1 -1
  109. package/lib/types/controllers/UnknownOperatingContextController.d.ts +1 -0
  110. package/lib/types/controllers/UnknownOperatingContextController.d.ts.map +1 -1
  111. package/lib/types/event/EventHandler.d.ts +19 -0
  112. package/lib/types/event/EventHandler.d.ts.map +1 -1
  113. package/lib/types/packageMetadata.d.ts +1 -1
  114. package/package.json +3 -3
  115. package/src/cache/BrowserCacheManager.ts +51 -4
  116. package/src/cache/CookieStorage.ts +12 -3
  117. package/src/cache/LocalStorage.ts +65 -3
  118. package/src/config/Configuration.ts +2 -1
  119. package/src/controllers/NestedAppAuthController.ts +13 -5
  120. package/src/controllers/StandardController.ts +23 -82
  121. package/src/controllers/UnknownOperatingContextController.ts +9 -1
  122. package/src/event/EventHandler.ts +78 -27
  123. package/src/packageMetadata.ts +1 -1
@@ -19,6 +19,7 @@ import {
19
19
  OIDC_DEFAULT_SCOPES,
20
20
  BaseAuthRequest,
21
21
  AccountFilter,
22
+ AuthError,
22
23
  } from "@azure/msal-common/browser";
23
24
  import { ITokenCache } from "../cache/ITokenCache.js";
24
25
  import { BrowserConfiguration } from "../config/Configuration.js";
@@ -111,6 +112,7 @@ export class NestedAppAuthController implements IController {
111
112
  ? new CryptoOps(this.logger, this.performanceClient, true)
112
113
  : DEFAULT_CRYPTO_IMPLEMENTATION;
113
114
 
115
+ this.eventHandler = new EventHandler(this.logger);
114
116
  // Initialize the browser storage class.
115
117
  this.browserStorage = this.operatingContext.isBrowserEnvironment()
116
118
  ? new BrowserCacheManager(
@@ -119,16 +121,16 @@ export class NestedAppAuthController implements IController {
119
121
  this.browserCrypto,
120
122
  this.logger,
121
123
  this.performanceClient,
124
+ this.eventHandler,
122
125
  buildStaticAuthorityOptions(this.config.auth)
123
126
  )
124
127
  : DEFAULT_BROWSER_CACHE_MANAGER(
125
128
  this.config.auth.clientId,
126
129
  this.logger,
127
- this.performanceClient
130
+ this.performanceClient,
131
+ this.eventHandler
128
132
  );
129
133
 
130
- this.eventHandler = new EventHandler(this.logger);
131
-
132
134
  this.nestedAppAuthAdapter = new NestedAppAuthAdapter(
133
135
  this.config.auth.clientId,
134
136
  this.config.auth.clientCapabilities,
@@ -250,7 +252,10 @@ export class NestedAppAuthController implements IController {
250
252
 
251
253
  return result;
252
254
  } catch (e) {
253
- const error = this.nestedAppAuthAdapter.fromBridgeError(e);
255
+ const error =
256
+ e instanceof AuthError
257
+ ? e
258
+ : this.nestedAppAuthAdapter.fromBridgeError(e);
254
259
  this.eventHandler.emitEvent(
255
260
  EventType.ACQUIRE_TOKEN_FAILURE,
256
261
  InteractionType.Popup,
@@ -347,7 +352,10 @@ export class NestedAppAuthController implements IController {
347
352
  });
348
353
  return result;
349
354
  } catch (e) {
350
- const error = this.nestedAppAuthAdapter.fromBridgeError(e);
355
+ const error =
356
+ e instanceof AuthError
357
+ ? e
358
+ : this.nestedAppAuthAdapter.fromBridgeError(e);
351
359
  this.eventHandler.emitEvent(
352
360
  EventType.ACQUIRE_TOKEN_FAILURE,
353
361
  InteractionType.Silent,
@@ -28,8 +28,6 @@ import {
28
28
  AccountFilter,
29
29
  buildStaticAuthorityOptions,
30
30
  InteractionRequiredAuthErrorCodes,
31
- PersistentCacheKeys,
32
- CacheManager,
33
31
  } from "@azure/msal-common/browser";
34
32
  import {
35
33
  BrowserCacheManager,
@@ -179,8 +177,6 @@ export class StandardController implements IController {
179
177
  private ssoSilentMeasurement?: InProgressPerformanceEvent;
180
178
  private acquireTokenByCodeAsyncMeasurement?: InProgressPerformanceEvent;
181
179
 
182
- // Flag which indicates if we're currently listening for account storage events
183
- private listeningToStorageEvents: boolean;
184
180
  /**
185
181
  * @constructor
186
182
  * Constructor for the PublicClientApplication used to instantiate the PublicClientApplication object
@@ -243,12 +239,14 @@ export class StandardController implements IController {
243
239
  this.browserCrypto,
244
240
  this.logger,
245
241
  this.performanceClient,
242
+ this.eventHandler,
246
243
  buildStaticAuthorityOptions(this.config.auth)
247
244
  )
248
245
  : DEFAULT_BROWSER_CACHE_MANAGER(
249
246
  this.config.auth.clientId,
250
247
  this.logger,
251
- this.performanceClient
248
+ this.performanceClient,
249
+ this.eventHandler
252
250
  );
253
251
 
254
252
  // initialize in memory storage for native flows
@@ -265,7 +263,8 @@ export class StandardController implements IController {
265
263
  nativeCacheOptions,
266
264
  this.browserCrypto,
267
265
  this.logger,
268
- this.performanceClient
266
+ this.performanceClient,
267
+ this.eventHandler
269
268
  );
270
269
 
271
270
  // Initialize the token cache
@@ -284,11 +283,6 @@ export class StandardController implements IController {
284
283
  // Register listener functions
285
284
  this.trackPageVisibilityWithMeasurement =
286
285
  this.trackPageVisibilityWithMeasurement.bind(this);
287
-
288
- // account storage events
289
- this.listeningToStorageEvents = false;
290
- this.handleAccountCacheChange =
291
- this.handleAccountCacheChange.bind(this);
292
286
  }
293
287
 
294
288
  static async createController(
@@ -1769,91 +1763,38 @@ export class StandardController implements IController {
1769
1763
 
1770
1764
  /**
1771
1765
  * Adds event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window
1766
+ * @deprecated These events will be raised by default and this method will be removed in a future major version.
1772
1767
  */
1773
1768
  enableAccountStorageEvents(): void {
1774
- if (typeof window === "undefined") {
1769
+ if (
1770
+ this.config.cache.cacheLocation !==
1771
+ BrowserCacheLocation.LocalStorage
1772
+ ) {
1773
+ this.logger.info(
1774
+ "Account storage events are only available when cacheLocation is set to localStorage"
1775
+ );
1775
1776
  return;
1776
1777
  }
1777
1778
 
1778
- if (!this.listeningToStorageEvents) {
1779
- this.logger.verbose("Adding account storage listener.");
1780
- this.listeningToStorageEvents = true;
1781
- window.addEventListener("storage", this.handleAccountCacheChange);
1782
- } else {
1783
- this.logger.verbose("Account storage listener already registered.");
1784
- }
1779
+ this.eventHandler.subscribeCrossTab();
1785
1780
  }
1786
1781
 
1787
1782
  /**
1788
1783
  * Removes event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window
1784
+ * @deprecated These events will be raised by default and this method will be removed in a future major version.
1789
1785
  */
1790
1786
  disableAccountStorageEvents(): void {
1791
- if (typeof window === "undefined") {
1792
- return;
1793
- }
1794
-
1795
- if (this.listeningToStorageEvents) {
1796
- this.logger.verbose("Removing account storage listener.");
1797
- window.removeEventListener(
1798
- "storage",
1799
- this.handleAccountCacheChange
1800
- );
1801
- this.listeningToStorageEvents = false;
1802
- } else {
1803
- this.logger.verbose("No account storage listener registered.");
1804
- }
1805
- }
1806
-
1807
- /**
1808
- * Emit account added/removed events when cached accounts are changed in a different tab or frame
1809
- */
1810
- protected handleAccountCacheChange(e: StorageEvent): void {
1811
- try {
1812
- // Handle active account filter change
1813
- if (e.key?.includes(PersistentCacheKeys.ACTIVE_ACCOUNT_FILTERS)) {
1814
- // This event has no payload, it only signals cross-tab app instances that the results of calling getActiveAccount() will have changed
1815
- this.eventHandler.emitEvent(EventType.ACTIVE_ACCOUNT_CHANGED);
1816
- }
1817
-
1818
- // Handle account object change
1819
- const cacheValue = e.newValue || e.oldValue;
1820
- if (!cacheValue) {
1821
- return;
1822
- }
1823
- const parsedValue = JSON.parse(cacheValue);
1824
- if (
1825
- typeof parsedValue !== "object" ||
1826
- !AccountEntity.isAccountEntity(parsedValue)
1827
- ) {
1828
- return;
1829
- }
1830
- const accountEntity = CacheManager.toObject<AccountEntity>(
1831
- new AccountEntity(),
1832
- parsedValue
1787
+ if (
1788
+ this.config.cache.cacheLocation !==
1789
+ BrowserCacheLocation.LocalStorage
1790
+ ) {
1791
+ this.logger.info(
1792
+ "Account storage events are only available when cacheLocation is set to localStorage"
1833
1793
  );
1834
- const accountInfo = accountEntity.getAccountInfo();
1835
- if (!e.oldValue && e.newValue) {
1836
- this.logger.info(
1837
- "Account was added to cache in a different window"
1838
- );
1839
- this.eventHandler.emitEvent(
1840
- EventType.ACCOUNT_ADDED,
1841
- undefined,
1842
- accountInfo
1843
- );
1844
- } else if (!e.newValue && e.oldValue) {
1845
- this.logger.info(
1846
- "Account was removed from cache in a different window"
1847
- );
1848
- this.eventHandler.emitEvent(
1849
- EventType.ACCOUNT_REMOVED,
1850
- undefined,
1851
- accountInfo
1852
- );
1853
- }
1854
- } catch (e) {
1855
1794
  return;
1856
1795
  }
1796
+
1797
+ this.eventHandler.unsubscribeCrossTab();
1857
1798
  }
1858
1799
 
1859
1800
  /**
@@ -40,6 +40,7 @@ import {
40
40
  import { EventCallbackFunction } from "../event/EventMessage.js";
41
41
  import { ClearCacheRequest } from "../request/ClearCacheRequest.js";
42
42
  import { EventType } from "../event/EventType.js";
43
+ import { EventHandler } from "../event/EventHandler.js";
43
44
 
44
45
  /**
45
46
  * UnknownOperatingContextController class
@@ -71,6 +72,9 @@ export class UnknownOperatingContextController implements IController {
71
72
  // Performance telemetry client
72
73
  protected readonly performanceClient: IPerformanceClient;
73
74
 
75
+ // Event handler
76
+ private readonly eventHandler: EventHandler;
77
+
74
78
  // Crypto interface implementation
75
79
  protected readonly browserCrypto: ICrypto;
76
80
 
@@ -98,6 +102,8 @@ export class UnknownOperatingContextController implements IController {
98
102
  ? new CryptoOps(this.logger, this.performanceClient)
99
103
  : DEFAULT_CRYPTO_IMPLEMENTATION;
100
104
 
105
+ this.eventHandler = new EventHandler(this.logger);
106
+
101
107
  // Initialize the browser storage class.
102
108
  this.browserStorage = this.isBrowserEnvironment
103
109
  ? new BrowserCacheManager(
@@ -106,12 +112,14 @@ export class UnknownOperatingContextController implements IController {
106
112
  this.browserCrypto,
107
113
  this.logger,
108
114
  this.performanceClient,
115
+ this.eventHandler,
109
116
  undefined
110
117
  )
111
118
  : DEFAULT_BROWSER_CACHE_MANAGER(
112
119
  this.config.auth.clientId,
113
120
  this.logger,
114
- this.performanceClient
121
+ this.performanceClient,
122
+ this.eventHandler
115
123
  );
116
124
  }
117
125
  getBrowserStorage(): BrowserCacheManager {
@@ -14,6 +14,8 @@ import {
14
14
  import { EventType } from "./EventType.js";
15
15
  import { createGuid } from "../utils/BrowserUtils.js";
16
16
 
17
+ const BROADCAST_CHANNEL_NAME = "msal.broadcast.event";
18
+
17
19
  export class EventHandler {
18
20
  // Callback for subscribing to events
19
21
  private eventCallbacks: Map<
@@ -21,10 +23,13 @@ export class EventHandler {
21
23
  [EventCallbackFunction, Array<EventType>]
22
24
  >;
23
25
  private logger: Logger;
26
+ private broadcastChannel: BroadcastChannel;
24
27
 
25
28
  constructor(logger?: Logger) {
26
29
  this.eventCallbacks = new Map();
27
30
  this.logger = logger || new Logger({});
31
+ this.broadcastChannel = new BroadcastChannel(BROADCAST_CHANNEL_NAME);
32
+ this.invokeCrossTabCallbacks = this.invokeCrossTabCallbacks.bind(this);
28
33
  }
29
34
 
30
35
  /**
@@ -77,34 +82,80 @@ export class EventHandler {
77
82
  payload?: EventPayload,
78
83
  error?: EventError
79
84
  ): void {
80
- if (typeof window !== "undefined") {
81
- const message: EventMessage = {
82
- eventType: eventType,
83
- interactionType: interactionType || null,
84
- payload: payload || null,
85
- error: error || null,
86
- timestamp: Date.now(),
87
- };
85
+ const message: EventMessage = {
86
+ eventType: eventType,
87
+ interactionType: interactionType || null,
88
+ payload: payload || null,
89
+ error: error || null,
90
+ timestamp: Date.now(),
91
+ };
88
92
 
89
- this.eventCallbacks.forEach(
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
- }
106
- }
107
- );
93
+ switch (eventType) {
94
+ case EventType.ACCOUNT_ADDED:
95
+ case EventType.ACCOUNT_REMOVED:
96
+ case EventType.ACTIVE_ACCOUNT_CHANGED:
97
+ // Send event to other open tabs / MSAL instances on same domain
98
+ this.broadcastChannel.postMessage(message);
99
+ break;
100
+ default:
101
+ // Emit event to callbacks registered in this instance
102
+ this.invokeCallbacks(message);
103
+ break;
108
104
  }
109
105
  }
106
+
107
+ /**
108
+ * Invoke registered callbacks
109
+ * @param message
110
+ */
111
+ private invokeCallbacks(message: EventMessage): void {
112
+ this.eventCallbacks.forEach(
113
+ (
114
+ [callback, eventTypes]: [
115
+ EventCallbackFunction,
116
+ Array<EventType>
117
+ ],
118
+ callbackId: string
119
+ ) => {
120
+ if (
121
+ eventTypes.length === 0 ||
122
+ eventTypes.includes(message.eventType)
123
+ ) {
124
+ this.logger.verbose(
125
+ `Emitting event to callback ${callbackId}: ${message.eventType}`
126
+ );
127
+ callback.apply(null, [message]);
128
+ }
129
+ }
130
+ );
131
+ }
132
+
133
+ /**
134
+ * Wrapper around invokeCallbacks to handle broadcast events received from other tabs/instances
135
+ * @param event
136
+ */
137
+ private invokeCrossTabCallbacks(event: MessageEvent): void {
138
+ const message = event.data as EventMessage;
139
+ this.invokeCallbacks(message);
140
+ }
141
+
142
+ /**
143
+ * Listen for events broadcasted from other tabs/instances
144
+ */
145
+ subscribeCrossTab(): void {
146
+ this.broadcastChannel.addEventListener(
147
+ "message",
148
+ this.invokeCrossTabCallbacks
149
+ );
150
+ }
151
+
152
+ /**
153
+ * Unsubscribe from broadcast events
154
+ */
155
+ unsubscribeCrossTab(): void {
156
+ this.broadcastChannel.removeEventListener(
157
+ "message",
158
+ this.invokeCrossTabCallbacks
159
+ );
160
+ }
110
161
  }
@@ -1,3 +1,3 @@
1
1
  /* eslint-disable header/header */
2
2
  export const name = "@azure/msal-browser";
3
- export const version = "4.1.0";
3
+ export const version = "4.2.1";