@azure/msal-browser 3.26.1 → 3.28.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 (168) 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/NativeRequest.d.ts +1 -0
  6. package/dist/broker/nativeBroker/NativeRequest.d.ts.map +1 -1
  7. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  8. package/dist/cache/AccountManager.mjs +1 -1
  9. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  10. package/dist/cache/BrowserCacheManager.d.ts +2 -38
  11. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  12. package/dist/cache/BrowserCacheManager.mjs +21 -115
  13. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  14. package/dist/cache/BrowserStorage.d.ts +3 -1
  15. package/dist/cache/BrowserStorage.d.ts.map +1 -1
  16. package/dist/cache/BrowserStorage.mjs +13 -8
  17. package/dist/cache/BrowserStorage.mjs.map +1 -1
  18. package/dist/cache/CookieStorage.d.ts +14 -0
  19. package/dist/cache/CookieStorage.d.ts.map +1 -0
  20. package/dist/cache/CookieStorage.mjs +62 -0
  21. package/dist/cache/CookieStorage.mjs.map +1 -0
  22. package/dist/cache/DatabaseStorage.mjs +1 -1
  23. package/dist/cache/LocalStorage.d.ts +10 -0
  24. package/dist/cache/LocalStorage.d.ts.map +1 -0
  25. package/dist/cache/LocalStorage.mjs +34 -0
  26. package/dist/cache/LocalStorage.mjs.map +1 -0
  27. package/dist/cache/MemoryStorage.mjs +1 -1
  28. package/dist/cache/SessionStorage.d.ts +10 -0
  29. package/dist/cache/SessionStorage.d.ts.map +1 -0
  30. package/dist/cache/SessionStorage.mjs +34 -0
  31. package/dist/cache/SessionStorage.mjs.map +1 -0
  32. package/dist/cache/TokenCache.mjs +1 -1
  33. package/dist/config/Configuration.d.ts.map +1 -1
  34. package/dist/config/Configuration.mjs +4 -3
  35. package/dist/config/Configuration.mjs.map +1 -1
  36. package/dist/controllers/ControllerFactory.mjs +1 -1
  37. package/dist/controllers/NestedAppAuthController.mjs +1 -1
  38. package/dist/controllers/StandardController.d.ts.map +1 -1
  39. package/dist/controllers/StandardController.mjs +1 -8
  40. package/dist/controllers/StandardController.mjs.map +1 -1
  41. package/dist/controllers/UnknownOperatingContextController.mjs +1 -1
  42. package/dist/crypto/BrowserCrypto.d.ts +2 -2
  43. package/dist/crypto/BrowserCrypto.d.ts.map +1 -1
  44. package/dist/crypto/BrowserCrypto.mjs +10 -7
  45. package/dist/crypto/BrowserCrypto.mjs.map +1 -1
  46. package/dist/crypto/CryptoOps.mjs +2 -2
  47. package/dist/crypto/CryptoOps.mjs.map +1 -1
  48. package/dist/crypto/PkceGenerator.mjs +1 -1
  49. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  50. package/dist/encode/Base64Decode.mjs +1 -1
  51. package/dist/encode/Base64Encode.mjs +1 -1
  52. package/dist/error/BrowserAuthError.d.ts +4 -2
  53. package/dist/error/BrowserAuthError.d.ts.map +1 -1
  54. package/dist/error/BrowserAuthError.mjs +8 -6
  55. package/dist/error/BrowserAuthError.mjs.map +1 -1
  56. package/dist/error/BrowserAuthErrorCodes.d.ts +2 -0
  57. package/dist/error/BrowserAuthErrorCodes.d.ts.map +1 -1
  58. package/dist/error/BrowserAuthErrorCodes.mjs +5 -3
  59. package/dist/error/BrowserAuthErrorCodes.mjs.map +1 -1
  60. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  61. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  62. package/dist/error/NativeAuthError.mjs +1 -1
  63. package/dist/error/NativeAuthErrorCodes.mjs +1 -1
  64. package/dist/error/NestedAppAuthError.mjs +1 -1
  65. package/dist/event/EventHandler.mjs +1 -1
  66. package/dist/event/EventMessage.mjs +1 -1
  67. package/dist/event/EventType.mjs +1 -1
  68. package/dist/index.d.ts +3 -0
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.mjs +3 -1
  71. package/dist/index.mjs.map +1 -1
  72. package/dist/interaction_client/BaseInteractionClient.d.ts.map +1 -1
  73. package/dist/interaction_client/BaseInteractionClient.mjs +2 -4
  74. package/dist/interaction_client/BaseInteractionClient.mjs.map +1 -1
  75. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  76. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  77. package/dist/interaction_client/NativeInteractionClient.mjs +25 -17
  78. package/dist/interaction_client/NativeInteractionClient.mjs.map +1 -1
  79. package/dist/interaction_client/PopupClient.mjs +1 -1
  80. package/dist/interaction_client/RedirectClient.mjs +1 -1
  81. package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
  82. package/dist/interaction_client/SilentCacheClient.mjs +1 -1
  83. package/dist/interaction_client/SilentIframeClient.mjs +1 -1
  84. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  85. package/dist/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  86. package/dist/interaction_client/StandardInteractionClient.mjs +6 -1
  87. package/dist/interaction_client/StandardInteractionClient.mjs.map +1 -1
  88. package/dist/interaction_handler/InteractionHandler.mjs +1 -1
  89. package/dist/interaction_handler/RedirectHandler.mjs +1 -1
  90. package/dist/interaction_handler/SilentHandler.mjs +1 -1
  91. package/dist/naa/BridgeError.mjs +1 -1
  92. package/dist/naa/BridgeProxy.mjs +1 -1
  93. package/dist/naa/BridgeStatusCode.mjs +1 -1
  94. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts.map +1 -1
  95. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +4 -5
  96. package/dist/naa/mapping/NestedAppAuthAdapter.mjs.map +1 -1
  97. package/dist/navigation/NavigationClient.mjs +1 -1
  98. package/dist/network/FetchClient.d.ts +0 -6
  99. package/dist/network/FetchClient.d.ts.map +1 -1
  100. package/dist/network/FetchClient.mjs +51 -32
  101. package/dist/network/FetchClient.mjs.map +1 -1
  102. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  103. package/dist/operatingcontext/NestedAppOperatingContext.mjs +1 -1
  104. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  105. package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
  106. package/dist/packageMetadata.d.ts +1 -1
  107. package/dist/packageMetadata.mjs +2 -2
  108. package/dist/request/RequestHelpers.mjs +1 -1
  109. package/dist/response/ResponseHandler.mjs +1 -1
  110. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  111. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  112. package/dist/utils/BrowserConstants.mjs +1 -1
  113. package/dist/utils/BrowserProtocolUtils.mjs +1 -1
  114. package/dist/utils/BrowserUtils.mjs +1 -1
  115. package/lib/msal-browser.cjs +627 -472
  116. package/lib/msal-browser.cjs.map +1 -1
  117. package/lib/msal-browser.js +627 -472
  118. package/lib/msal-browser.js.map +1 -1
  119. package/lib/msal-browser.min.js +66 -66
  120. package/lib/types/broker/nativeBroker/NativeRequest.d.ts +1 -0
  121. package/lib/types/broker/nativeBroker/NativeRequest.d.ts.map +1 -1
  122. package/lib/types/cache/BrowserCacheManager.d.ts +2 -38
  123. package/lib/types/cache/BrowserCacheManager.d.ts.map +1 -1
  124. package/lib/types/cache/BrowserStorage.d.ts +3 -1
  125. package/lib/types/cache/BrowserStorage.d.ts.map +1 -1
  126. package/lib/types/cache/CookieStorage.d.ts +14 -0
  127. package/lib/types/cache/CookieStorage.d.ts.map +1 -0
  128. package/lib/types/cache/LocalStorage.d.ts +10 -0
  129. package/lib/types/cache/LocalStorage.d.ts.map +1 -0
  130. package/lib/types/cache/SessionStorage.d.ts +10 -0
  131. package/lib/types/cache/SessionStorage.d.ts.map +1 -0
  132. package/lib/types/config/Configuration.d.ts.map +1 -1
  133. package/lib/types/controllers/StandardController.d.ts.map +1 -1
  134. package/lib/types/crypto/BrowserCrypto.d.ts +2 -2
  135. package/lib/types/crypto/BrowserCrypto.d.ts.map +1 -1
  136. package/lib/types/error/BrowserAuthError.d.ts +4 -2
  137. package/lib/types/error/BrowserAuthError.d.ts.map +1 -1
  138. package/lib/types/error/BrowserAuthErrorCodes.d.ts +2 -0
  139. package/lib/types/error/BrowserAuthErrorCodes.d.ts.map +1 -1
  140. package/lib/types/index.d.ts +3 -0
  141. package/lib/types/index.d.ts.map +1 -1
  142. package/lib/types/interaction_client/BaseInteractionClient.d.ts.map +1 -1
  143. package/lib/types/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  144. package/lib/types/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  145. package/lib/types/naa/mapping/NestedAppAuthAdapter.d.ts.map +1 -1
  146. package/lib/types/network/FetchClient.d.ts +0 -6
  147. package/lib/types/network/FetchClient.d.ts.map +1 -1
  148. package/lib/types/packageMetadata.d.ts +1 -1
  149. package/package.json +3 -3
  150. package/src/broker/nativeBroker/NativeRequest.ts +1 -0
  151. package/src/cache/BrowserCacheManager.ts +27 -141
  152. package/src/cache/BrowserStorage.ts +11 -11
  153. package/src/cache/CookieStorage.ts +80 -0
  154. package/src/cache/LocalStorage.ts +40 -0
  155. package/src/cache/SessionStorage.ts +40 -0
  156. package/src/config/Configuration.ts +3 -1
  157. package/src/controllers/StandardController.ts +0 -7
  158. package/src/crypto/BrowserCrypto.ts +15 -6
  159. package/src/crypto/CryptoOps.ts +1 -1
  160. package/src/error/BrowserAuthError.ts +11 -4
  161. package/src/error/BrowserAuthErrorCodes.ts +2 -0
  162. package/src/index.ts +3 -0
  163. package/src/interaction_client/BaseInteractionClient.ts +1 -4
  164. package/src/interaction_client/NativeInteractionClient.ts +35 -25
  165. package/src/interaction_client/StandardInteractionClient.ts +6 -0
  166. package/src/naa/mapping/NestedAppAuthAdapter.ts +4 -5
  167. package/src/network/FetchClient.ts +67 -40
  168. package/src/packageMetadata.ts +1 -1
@@ -52,7 +52,8 @@ import {
52
52
  InMemoryCacheKeys,
53
53
  StaticCacheKeys,
54
54
  } from "../utils/BrowserConstants.js";
55
- import { BrowserStorage } from "./BrowserStorage.js";
55
+ import { LocalStorage } from "./LocalStorage.js";
56
+ import { SessionStorage } from "./SessionStorage.js";
56
57
  import { MemoryStorage } from "./MemoryStorage.js";
57
58
  import { IWindowStorage } from "./IWindowStorage.js";
58
59
  import { extractBrowserRequestState } from "../utils/BrowserProtocolUtils.js";
@@ -64,6 +65,7 @@ import { RedirectRequest } from "../request/RedirectRequest.js";
64
65
  import { PopupRequest } from "../request/PopupRequest.js";
65
66
  import { base64Decode } from "../encode/Base64Decode.js";
66
67
  import { base64Encode } from "../encode/Base64Encode.js";
68
+ import { CookieStorage } from "./CookieStorage.js";
67
69
 
68
70
  /**
69
71
  * This class implements the cache storage interface for MSAL through browser local or session storage.
@@ -79,14 +81,13 @@ export class BrowserCacheManager extends CacheManager {
79
81
  protected internalStorage: MemoryStorage<string>;
80
82
  // Temporary cache
81
83
  protected temporaryCacheStorage: IWindowStorage<string>;
84
+ // Cookie storage
85
+ protected cookieStorage: CookieStorage;
82
86
  // Logger instance
83
87
  protected logger: Logger;
84
88
  // Telemetry perf client
85
89
  protected performanceClient?: IPerformanceClient;
86
90
 
87
- // Cookie life calculation (hours * minutes * seconds * ms)
88
- protected readonly COOKIE_LIFE_MULTIPLIER = 24 * 60 * 60 * 1000;
89
-
90
91
  constructor(
91
92
  clientId: string,
92
93
  cacheConfig: Required<CacheOptions>,
@@ -102,10 +103,10 @@ export class BrowserCacheManager extends CacheManager {
102
103
  this.browserStorage = this.setupBrowserStorage(
103
104
  this.cacheConfig.cacheLocation
104
105
  );
105
- this.temporaryCacheStorage = this.setupTemporaryCacheStorage(
106
- this.cacheConfig.temporaryCacheLocation,
107
- this.cacheConfig.cacheLocation
106
+ this.temporaryCacheStorage = this.setupBrowserStorage(
107
+ this.cacheConfig.temporaryCacheLocation
108
108
  );
109
+ this.cookieStorage = new CookieStorage();
109
110
 
110
111
  // Migrate cache entries from older versions of MSAL.
111
112
  if (cacheConfig.cacheMigrationEnabled) {
@@ -123,51 +124,23 @@ export class BrowserCacheManager extends CacheManager {
123
124
  protected setupBrowserStorage(
124
125
  cacheLocation: BrowserCacheLocation | string
125
126
  ): IWindowStorage<string> {
126
- switch (cacheLocation) {
127
- case BrowserCacheLocation.LocalStorage:
128
- case BrowserCacheLocation.SessionStorage:
129
- try {
130
- return new BrowserStorage(cacheLocation);
131
- } catch (e) {
132
- this.logger.verbose(e as string);
127
+ try {
128
+ switch (cacheLocation) {
129
+ case BrowserCacheLocation.LocalStorage:
130
+ return new LocalStorage();
131
+ case BrowserCacheLocation.SessionStorage:
132
+ return new SessionStorage();
133
+ case BrowserCacheLocation.MemoryStorage:
134
+ default:
133
135
  break;
134
- }
135
- case BrowserCacheLocation.MemoryStorage:
136
- default:
137
- break;
136
+ }
137
+ } catch (e) {
138
+ this.logger.error(e as string);
138
139
  }
139
140
  this.cacheConfig.cacheLocation = BrowserCacheLocation.MemoryStorage;
140
141
  return new MemoryStorage();
141
142
  }
142
143
 
143
- /**
144
- * Returns a window storage class implementing the IWindowStorage interface that corresponds to the configured temporaryCacheLocation.
145
- * @param temporaryCacheLocation
146
- * @param cacheLocation
147
- */
148
- protected setupTemporaryCacheStorage(
149
- temporaryCacheLocation: BrowserCacheLocation | string,
150
- cacheLocation: BrowserCacheLocation | string
151
- ): IWindowStorage<string> {
152
- switch (cacheLocation) {
153
- case BrowserCacheLocation.LocalStorage:
154
- case BrowserCacheLocation.SessionStorage:
155
- try {
156
- // Temporary cache items will always be stored in session storage to mitigate problems caused by multiple tabs
157
- return new BrowserStorage(
158
- temporaryCacheLocation ||
159
- BrowserCacheLocation.SessionStorage
160
- );
161
- } catch (e) {
162
- this.logger.verbose(e as string);
163
- return this.internalStorage;
164
- }
165
- case BrowserCacheLocation.MemoryStorage:
166
- default:
167
- return this.internalStorage;
168
- }
169
- }
170
-
171
144
  /**
172
145
  * Migrate all old cache entries to new schema. No rollback supported.
173
146
  * @param storeAuthStateInCookie
@@ -1144,7 +1117,7 @@ export class BrowserCacheManager extends CacheManager {
1144
1117
  getTemporaryCache(cacheKey: string, generateKey?: boolean): string | null {
1145
1118
  const key = generateKey ? this.generateCacheKey(cacheKey) : cacheKey;
1146
1119
  if (this.cacheConfig.storeAuthStateInCookie) {
1147
- const itemCookie = this.getItemCookie(key);
1120
+ const itemCookie = this.cookieStorage.getItem(key);
1148
1121
  if (itemCookie) {
1149
1122
  this.logger.trace(
1150
1123
  "BrowserCacheManager.getTemporaryCache: storeAuthStateInCookies set to true, retrieving from cookies"
@@ -1198,7 +1171,12 @@ export class BrowserCacheManager extends CacheManager {
1198
1171
  this.logger.trace(
1199
1172
  "BrowserCacheManager.setTemporaryCache: storeAuthStateInCookie set to true, setting item cookie"
1200
1173
  );
1201
- this.setItemCookie(key, value);
1174
+ this.cookieStorage.setItem(
1175
+ key,
1176
+ value,
1177
+ undefined,
1178
+ this.cacheConfig.secureCookies
1179
+ );
1202
1180
  }
1203
1181
  }
1204
1182
 
@@ -1221,7 +1199,7 @@ export class BrowserCacheManager extends CacheManager {
1221
1199
  this.logger.trace(
1222
1200
  "BrowserCacheManager.removeItem: storeAuthStateInCookie is true, clearing item cookie"
1223
1201
  );
1224
- this.clearItemCookie(key);
1202
+ this.cookieStorage.removeItem(key);
1225
1203
  }
1226
1204
  }
1227
1205
 
@@ -1301,96 +1279,6 @@ export class BrowserCacheManager extends CacheManager {
1301
1279
  }
1302
1280
  }
1303
1281
 
1304
- /**
1305
- * Add value to cookies
1306
- * @param cookieName
1307
- * @param cookieValue
1308
- * @param expires
1309
- * @deprecated
1310
- */
1311
- setItemCookie(
1312
- cookieName: string,
1313
- cookieValue: string,
1314
- expires?: number
1315
- ): void {
1316
- let cookieStr = `${encodeURIComponent(cookieName)}=${encodeURIComponent(
1317
- cookieValue
1318
- )};path=/;SameSite=Lax;`;
1319
- if (expires) {
1320
- const expireTime = this.getCookieExpirationTime(expires);
1321
- cookieStr += `expires=${expireTime};`;
1322
- }
1323
-
1324
- if (this.cacheConfig.secureCookies) {
1325
- cookieStr += "Secure;";
1326
- }
1327
-
1328
- document.cookie = cookieStr;
1329
- }
1330
-
1331
- /**
1332
- * Get one item by key from cookies
1333
- * @param cookieName
1334
- * @deprecated
1335
- */
1336
- getItemCookie(cookieName: string): string {
1337
- const name = `${encodeURIComponent(cookieName)}=`;
1338
- const cookieList = document.cookie.split(";");
1339
- for (let i: number = 0; i < cookieList.length; i++) {
1340
- let cookie = cookieList[i];
1341
- while (cookie.charAt(0) === " ") {
1342
- cookie = cookie.substring(1);
1343
- }
1344
- if (cookie.indexOf(name) === 0) {
1345
- return decodeURIComponent(
1346
- cookie.substring(name.length, cookie.length)
1347
- );
1348
- }
1349
- }
1350
- return Constants.EMPTY_STRING;
1351
- }
1352
-
1353
- /**
1354
- * Clear all msal-related cookies currently set in the browser. Should only be used to clear temporary cache items.
1355
- * @deprecated
1356
- */
1357
- clearMsalCookies(): void {
1358
- const cookiePrefix = `${Constants.CACHE_PREFIX}.${this.clientId}`;
1359
- const cookieList = document.cookie.split(";");
1360
- cookieList.forEach((cookie: string): void => {
1361
- while (cookie.charAt(0) === " ") {
1362
- // eslint-disable-next-line no-param-reassign
1363
- cookie = cookie.substring(1);
1364
- }
1365
- if (cookie.indexOf(cookiePrefix) === 0) {
1366
- const cookieKey = cookie.split("=")[0];
1367
- this.clearItemCookie(cookieKey);
1368
- }
1369
- });
1370
- }
1371
-
1372
- /**
1373
- * Clear an item in the cookies by key
1374
- * @param cookieName
1375
- * @deprecated
1376
- */
1377
- clearItemCookie(cookieName: string): void {
1378
- this.setItemCookie(cookieName, Constants.EMPTY_STRING, -1);
1379
- }
1380
-
1381
- /**
1382
- * Get cookie expiration time
1383
- * @param cookieLifeDays
1384
- * @deprecated
1385
- */
1386
- getCookieExpirationTime(cookieLifeDays: number): string {
1387
- const today = new Date();
1388
- const expr = new Date(
1389
- today.getTime() + cookieLifeDays * this.COOKIE_LIFE_MULTIPLIER
1390
- );
1391
- return expr.toUTCString();
1392
- }
1393
-
1394
1282
  /**
1395
1283
  * Prepend msal.<client-id> to each key; Skip for any JSON object as Key (defined schemas do not need the key appended: AccessToken Keys or the upcoming schema)
1396
1284
  * @param key
@@ -1570,7 +1458,6 @@ export class BrowserCacheManager extends CacheManager {
1570
1458
  );
1571
1459
  this.resetRequestCache(cachedState || Constants.EMPTY_STRING);
1572
1460
  }
1573
- this.clearMsalCookies();
1574
1461
  }
1575
1462
 
1576
1463
  /**
@@ -1609,7 +1496,6 @@ export class BrowserCacheManager extends CacheManager {
1609
1496
  this.resetRequestCache(stateValue);
1610
1497
  }
1611
1498
  });
1612
- this.clearMsalCookies();
1613
1499
  this.setInteractionInProgress(false);
1614
1500
  }
1615
1501
 
@@ -9,21 +9,21 @@ import {
9
9
  } from "../error/BrowserConfigurationAuthError.js";
10
10
  import { BrowserCacheLocation } from "../utils/BrowserConstants.js";
11
11
  import { IWindowStorage } from "./IWindowStorage.js";
12
+ import { LocalStorage } from "./LocalStorage.js";
13
+ import { SessionStorage } from "./SessionStorage.js";
12
14
 
15
+ /**
16
+ * @deprecated This class will be removed in a future major version
17
+ */
13
18
  export class BrowserStorage implements IWindowStorage<string> {
14
- private windowStorage: Storage;
19
+ private windowStorage: IWindowStorage<string>;
15
20
 
16
21
  constructor(cacheLocation: string) {
17
- this.validateWindowStorage(cacheLocation);
18
- this.windowStorage = window[cacheLocation];
19
- }
20
-
21
- private validateWindowStorage(cacheLocation: string): void {
22
- if (
23
- (cacheLocation !== BrowserCacheLocation.LocalStorage &&
24
- cacheLocation !== BrowserCacheLocation.SessionStorage) ||
25
- !window[cacheLocation]
26
- ) {
22
+ if (cacheLocation === BrowserCacheLocation.LocalStorage) {
23
+ this.windowStorage = new LocalStorage();
24
+ } else if (cacheLocation === BrowserCacheLocation.SessionStorage) {
25
+ this.windowStorage = new SessionStorage();
26
+ } else {
27
27
  throw createBrowserConfigurationAuthError(
28
28
  BrowserConfigurationAuthErrorCodes.storageNotSupported
29
29
  );
@@ -0,0 +1,80 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { IWindowStorage } from "./IWindowStorage.js";
7
+
8
+ // Cookie life calculation (hours * minutes * seconds * ms)
9
+ const COOKIE_LIFE_MULTIPLIER = 24 * 60 * 60 * 1000;
10
+
11
+ export class CookieStorage implements IWindowStorage<string> {
12
+ getItem(key: string): string | null {
13
+ const name = `${encodeURIComponent(key)}`;
14
+ const cookieList = document.cookie.split(";");
15
+ for (let i = 0; i < cookieList.length; i++) {
16
+ const cookie = cookieList[i];
17
+ const [key, ...rest] = decodeURIComponent(cookie).trim().split("=");
18
+ const value = rest.join("=");
19
+
20
+ if (key === name) {
21
+ return value;
22
+ }
23
+ }
24
+ return "";
25
+ }
26
+
27
+ setItem(
28
+ key: string,
29
+ value: string,
30
+ cookieLifeDays?: number,
31
+ secure: boolean = true
32
+ ): void {
33
+ let cookieStr = `${encodeURIComponent(key)}=${encodeURIComponent(
34
+ value
35
+ )};path=/;SameSite=Lax;`;
36
+
37
+ if (cookieLifeDays) {
38
+ const expireTime = getCookieExpirationTime(cookieLifeDays);
39
+ cookieStr += `expires=${expireTime};`;
40
+ }
41
+
42
+ if (secure) {
43
+ cookieStr += "Secure;";
44
+ }
45
+
46
+ document.cookie = cookieStr;
47
+ }
48
+
49
+ removeItem(key: string): void {
50
+ // Setting expiration to -1 removes it
51
+ this.setItem(key, "", -1);
52
+ }
53
+
54
+ getKeys(): string[] {
55
+ const cookieList = document.cookie.split(";");
56
+ const keys: Array<string> = [];
57
+ cookieList.forEach((cookie) => {
58
+ const cookieParts = decodeURIComponent(cookie).trim().split("=");
59
+ keys.push(cookieParts[0]);
60
+ });
61
+
62
+ return keys;
63
+ }
64
+
65
+ containsKey(key: string): boolean {
66
+ return this.getKeys().includes(key);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Get cookie expiration time
72
+ * @param cookieLifeDays
73
+ */
74
+ export function getCookieExpirationTime(cookieLifeDays: number): string {
75
+ const today = new Date();
76
+ const expr = new Date(
77
+ today.getTime() + cookieLifeDays * COOKIE_LIFE_MULTIPLIER
78
+ );
79
+ return expr.toUTCString();
80
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ BrowserConfigurationAuthErrorCodes,
8
+ createBrowserConfigurationAuthError,
9
+ } from "../error/BrowserConfigurationAuthError.js";
10
+ import { IWindowStorage } from "./IWindowStorage.js";
11
+
12
+ export class LocalStorage implements IWindowStorage<string> {
13
+ constructor() {
14
+ if (!window.localStorage) {
15
+ throw createBrowserConfigurationAuthError(
16
+ BrowserConfigurationAuthErrorCodes.storageNotSupported
17
+ );
18
+ }
19
+ }
20
+
21
+ getItem(key: string): string | null {
22
+ return window.localStorage.getItem(key);
23
+ }
24
+
25
+ setItem(key: string, value: string): void {
26
+ window.localStorage.setItem(key, value);
27
+ }
28
+
29
+ removeItem(key: string): void {
30
+ window.localStorage.removeItem(key);
31
+ }
32
+
33
+ getKeys(): string[] {
34
+ return Object.keys(window.localStorage);
35
+ }
36
+
37
+ containsKey(key: string): boolean {
38
+ return window.localStorage.hasOwnProperty(key);
39
+ }
40
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ BrowserConfigurationAuthErrorCodes,
8
+ createBrowserConfigurationAuthError,
9
+ } from "../error/BrowserConfigurationAuthError.js";
10
+ import { IWindowStorage } from "./IWindowStorage.js";
11
+
12
+ export class SessionStorage implements IWindowStorage<string> {
13
+ constructor() {
14
+ if (!window.sessionStorage) {
15
+ throw createBrowserConfigurationAuthError(
16
+ BrowserConfigurationAuthErrorCodes.storageNotSupported
17
+ );
18
+ }
19
+ }
20
+
21
+ getItem(key: string): string | null {
22
+ return window.sessionStorage.getItem(key);
23
+ }
24
+
25
+ setItem(key: string, value: string): void {
26
+ window.sessionStorage.setItem(key, value);
27
+ }
28
+
29
+ removeItem(key: string): void {
30
+ window.sessionStorage.removeItem(key);
31
+ }
32
+
33
+ getKeys(): string[] {
34
+ return Object.keys(window.sessionStorage);
35
+ }
36
+
37
+ containsKey(key: string): boolean {
38
+ return window.sessionStorage.hasOwnProperty(key);
39
+ }
40
+ }
@@ -30,6 +30,7 @@ import {
30
30
  import { INavigationClient } from "../navigation/INavigationClient.js";
31
31
  import { NavigationClient } from "../navigation/NavigationClient.js";
32
32
  import { FetchClient } from "../network/FetchClient.js";
33
+ import * as BrowserUtils from "../utils/BrowserUtils.js";
33
34
 
34
35
  // Default timeout for popup windows and iframes in milliseconds
35
36
  export const DEFAULT_POPUP_TIMEOUT_MS = 60000;
@@ -273,7 +274,8 @@ export function buildConfiguration(
273
274
  knownAuthorities: [],
274
275
  cloudDiscoveryMetadata: Constants.EMPTY_STRING,
275
276
  authorityMetadata: Constants.EMPTY_STRING,
276
- redirectUri: Constants.EMPTY_STRING,
277
+ redirectUri:
278
+ typeof window !== "undefined" ? BrowserUtils.getCurrentUri() : "",
277
279
  postLogoutRedirectUri: Constants.EMPTY_STRING,
278
280
  navigateToLoginRequestUrl: true,
279
281
  clientCapabilities: [],
@@ -781,7 +781,6 @@ export class StandardController implements IController {
781
781
  atPopupMeasurement.end({
782
782
  success: true,
783
783
  isNativeBroker: true,
784
- requestId: response.requestId,
785
784
  accountType: getAccountType(response.account),
786
785
  });
787
786
  return response;
@@ -834,7 +833,6 @@ export class StandardController implements IController {
834
833
 
835
834
  atPopupMeasurement.end({
836
835
  success: true,
837
- requestId: result.requestId,
838
836
  accessTokenSize: result.accessToken.length,
839
837
  idTokenSize: result.idToken.length,
840
838
  accountType: getAccountType(result.account),
@@ -971,7 +969,6 @@ export class StandardController implements IController {
971
969
  this.ssoSilentMeasurement?.end({
972
970
  success: true,
973
971
  isNativeBroker: response.fromNativeBroker,
974
- requestId: response.requestId,
975
972
  accessTokenSize: response.accessToken.length,
976
973
  idTokenSize: response.idToken.length,
977
974
  accountType: getAccountType(response.account),
@@ -1056,7 +1053,6 @@ export class StandardController implements IController {
1056
1053
  atbcMeasurement.end({
1057
1054
  success: true,
1058
1055
  isNativeBroker: result.fromNativeBroker,
1059
- requestId: result.requestId,
1060
1056
  accessTokenSize: result.accessToken.length,
1061
1057
  idTokenSize: result.idToken.length,
1062
1058
  accountType: getAccountType(result.account),
@@ -1173,7 +1169,6 @@ export class StandardController implements IController {
1173
1169
  success: true,
1174
1170
  fromCache: response.fromCache,
1175
1171
  isNativeBroker: response.fromNativeBroker,
1176
- requestId: response.requestId,
1177
1172
  });
1178
1173
  return response;
1179
1174
  })
@@ -2035,7 +2030,6 @@ export class StandardController implements IController {
2035
2030
  fromCache: result.fromCache,
2036
2031
  isNativeBroker: result.fromNativeBroker,
2037
2032
  cacheLookupPolicy: request.cacheLookupPolicy,
2038
- requestId: result.requestId,
2039
2033
  accessTokenSize: result.accessToken.length,
2040
2034
  idTokenSize: result.idToken.length,
2041
2035
  });
@@ -2223,7 +2217,6 @@ export class StandardController implements IController {
2223
2217
  {
2224
2218
  fromCache: response.fromCache,
2225
2219
  isNativeBroker: response.fromNativeBroker,
2226
- requestId: response.requestId,
2227
2220
  },
2228
2221
  request.correlationId
2229
2222
  );
@@ -9,7 +9,6 @@ import {
9
9
  } from "../error/BrowserAuthError.js";
10
10
  import {
11
11
  IPerformanceClient,
12
- Logger,
13
12
  PerformanceEvents,
14
13
  } from "@azure/msal-common/browser";
15
14
  import { KEY_FORMAT_JWK } from "../utils/BrowserConstants.js";
@@ -36,6 +35,8 @@ const UUID_CHARS = "0123456789abcdef";
36
35
  // Array to store UINT32 random value
37
36
  const UINT32_ARR = new Uint32Array(1);
38
37
 
38
+ const SUBTLE_SUBERROR = "crypto_subtle_undefined";
39
+
39
40
  const keygenAlgorithmOptions: RsaHashedKeyGenParams = {
40
41
  name: PKCS1_V15_KEYGEN_ALG,
41
42
  hash: S256_HASH_ALG,
@@ -46,13 +47,21 @@ const keygenAlgorithmOptions: RsaHashedKeyGenParams = {
46
47
  /**
47
48
  * Check whether browser crypto is available.
48
49
  */
49
- export function validateCryptoAvailable(logger: Logger): void {
50
- if ("crypto" in window) {
51
- logger.verbose("BrowserCrypto: modern crypto interface available");
52
- } else {
53
- logger.error("BrowserCrypto: crypto interface is unavailable");
50
+ export function validateCryptoAvailable(): void {
51
+ if (!window) {
52
+ throw createBrowserAuthError(
53
+ BrowserAuthErrorCodes.nonBrowserEnvironment
54
+ );
55
+ }
56
+ if (!window.crypto) {
54
57
  throw createBrowserAuthError(BrowserAuthErrorCodes.cryptoNonExistent);
55
58
  }
59
+ if (!window.crypto.subtle) {
60
+ throw createBrowserAuthError(
61
+ BrowserAuthErrorCodes.cryptoNonExistent,
62
+ SUBTLE_SUBERROR
63
+ );
64
+ }
56
65
  }
57
66
 
58
67
  /**
@@ -53,7 +53,7 @@ export class CryptoOps implements ICrypto {
53
53
  constructor(logger: Logger, performanceClient?: IPerformanceClient) {
54
54
  this.logger = logger;
55
55
  // Browser crypto needs to be validated first before any other classes can be set.
56
- BrowserCrypto.validateCryptoAvailable(logger);
56
+ BrowserCrypto.validateCryptoAvailable();
57
57
  this.cache = new AsyncMemoryStorage<CachedKeyPair>(this.logger);
58
58
  this.performanceClient = performanceClient;
59
59
  }
@@ -92,6 +92,10 @@ export const BrowserAuthErrorMessages = {
92
92
  "Invalid base64 encoded string.",
93
93
  [BrowserAuthErrorCodes.invalidPopTokenRequest]:
94
94
  "Invalid PoP token request. The request should not have both a popKid value and signPopToken set to true.",
95
+ [BrowserAuthErrorCodes.failedToBuildHeaders]:
96
+ "Failed to build request headers object.",
97
+ [BrowserAuthErrorCodes.failedToParseHeaders]:
98
+ "Failed to parse response headers",
95
99
  };
96
100
 
97
101
  /**
@@ -347,14 +351,17 @@ export const BrowserAuthErrorMessage = {
347
351
  * Browser library error class thrown by the MSAL.js library for SPAs
348
352
  */
349
353
  export class BrowserAuthError extends AuthError {
350
- constructor(errorCode: string) {
351
- super(errorCode, BrowserAuthErrorMessages[errorCode]);
354
+ constructor(errorCode: string, subError?: string) {
355
+ super(errorCode, BrowserAuthErrorMessages[errorCode], subError);
352
356
 
353
357
  Object.setPrototypeOf(this, BrowserAuthError.prototype);
354
358
  this.name = "BrowserAuthError";
355
359
  }
356
360
  }
357
361
 
358
- export function createBrowserAuthError(errorCode: string): BrowserAuthError {
359
- return new BrowserAuthError(errorCode);
362
+ export function createBrowserAuthError(
363
+ errorCode: string,
364
+ subError?: string
365
+ ): BrowserAuthError {
366
+ return new BrowserAuthError(errorCode, subError);
360
367
  }
@@ -56,3 +56,5 @@ export const uninitializedPublicClientApplication =
56
56
  export const nativePromptNotSupported = "native_prompt_not_supported";
57
57
  export const invalidBase64String = "invalid_base64_string";
58
58
  export const invalidPopTokenRequest = "invalid_pop_token_request";
59
+ export const failedToBuildHeaders = "failed_to_build_headers";
60
+ export const failedToParseHeaders = "failed_to_parse_headers";
package/src/index.ts CHANGED
@@ -75,6 +75,9 @@ export { ITokenCache } from "./cache/ITokenCache.js";
75
75
  // Storage
76
76
  export { MemoryStorage } from "./cache/MemoryStorage.js";
77
77
  export { BrowserStorage } from "./cache/BrowserStorage.js";
78
+ export { LocalStorage } from "./cache/LocalStorage.js";
79
+ export { SessionStorage } from "./cache/SessionStorage.js";
80
+ export { IWindowStorage } from "./cache/IWindowStorage.js";
78
81
 
79
82
  // Events
80
83
  export {
@@ -140,10 +140,7 @@ export abstract class BaseInteractionClient {
140
140
  */
141
141
  getRedirectUri(requestRedirectUri?: string): string {
142
142
  this.logger.verbose("getRedirectUri called");
143
- const redirectUri =
144
- requestRedirectUri ||
145
- this.config.auth.redirectUri ||
146
- BrowserUtils.getCurrentUri();
143
+ const redirectUri = requestRedirectUri || this.config.auth.redirectUri;
147
144
  return UrlString.getAbsoluteUrl(
148
145
  redirectUri,
149
146
  BrowserUtils.getCurrentUri()