@azure/msal-browser 4.1.0 → 4.2.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.
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 +4 -4
  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 +261 -188
  94. package/lib/msal-browser.cjs.map +1 -1
  95. package/lib/msal-browser.js +261 -188
  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 +4 -3
  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
@@ -111,6 +111,7 @@ export class NestedAppAuthController implements IController {
111
111
  ? new CryptoOps(this.logger, this.performanceClient, true)
112
112
  : DEFAULT_CRYPTO_IMPLEMENTATION;
113
113
 
114
+ this.eventHandler = new EventHandler(this.logger);
114
115
  // Initialize the browser storage class.
115
116
  this.browserStorage = this.operatingContext.isBrowserEnvironment()
116
117
  ? new BrowserCacheManager(
@@ -119,16 +120,16 @@ export class NestedAppAuthController implements IController {
119
120
  this.browserCrypto,
120
121
  this.logger,
121
122
  this.performanceClient,
123
+ this.eventHandler,
122
124
  buildStaticAuthorityOptions(this.config.auth)
123
125
  )
124
126
  : DEFAULT_BROWSER_CACHE_MANAGER(
125
127
  this.config.auth.clientId,
126
128
  this.logger,
127
- this.performanceClient
129
+ this.performanceClient,
130
+ this.eventHandler
128
131
  );
129
132
 
130
- this.eventHandler = new EventHandler(this.logger);
131
-
132
133
  this.nestedAppAuthAdapter = new NestedAppAuthAdapter(
133
134
  this.config.auth.clientId,
134
135
  this.config.auth.clientCapabilities,
@@ -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.0";