From 0cb830576e690fceae0bdf475754119bd4dad8c8 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Fri, 11 Apr 2025 20:44:45 -0700 Subject: [PATCH 01/24] Deprecate temporaryCacheLocation --- lib/msal-browser/docs/caching.md | 3 +++ lib/msal-browser/src/config/Configuration.ts | 2 ++ 2 files changed, 5 insertions(+) diff --git a/lib/msal-browser/docs/caching.md b/lib/msal-browser/docs/caching.md index 0661f06c5b..c93368fa49 100644 --- a/lib/msal-browser/docs/caching.md +++ b/lib/msal-browser/docs/caching.md @@ -71,6 +71,9 @@ To faciliate efficient token acquisition while maintaining a good UX, MSAL cache > :bulb: The authorization code is only stored in memory and will be discarded after redeeming it for tokens. ## Warning :warning: + +**NOTE: `temporaryCacheLocation` is deprecated as of MSAL v5 and will be removed in a future release.** + Overriding `temporaryCacheLocation` should be done with caution. Specifically when choosing `localStorage`. Interaction in more than one tab/window will not be supported and you may receive `interaction_in_progress` errors unexpectedly. This is an escape hatch, not a fully supported feature. When using MSAL.js with the default configuration in a scenario where the user is redirected after successful authentication in a new window or tab, the OAuth 2.0 Authorization Code with PKCE flow will be interrupted. In this case, the original window or tab where the authentication state (code verifier and challenge) are stored, will be lost, and the authentication flow will fail. diff --git a/lib/msal-browser/src/config/Configuration.ts b/lib/msal-browser/src/config/Configuration.ts index dbf839f1e4..e04e7b98a5 100644 --- a/lib/msal-browser/src/config/Configuration.ts +++ b/lib/msal-browser/src/config/Configuration.ts @@ -122,6 +122,8 @@ export type CacheOptions = { */ cacheLocation?: BrowserCacheLocation | string; /** + * @deprecated + * temporaryCacheLocation is deprecated and will be removed in a future release. * Used to specify the temporaryCacheLocation user wants to set. Valid values are "localStorage", "sessionStorage" and "memoryStorage". */ temporaryCacheLocation?: BrowserCacheLocation | string; From becbd55154cf8b8f05ebdace656d0aa538c1699a Mon Sep 17 00:00:00 2001 From: joarroyo Date: Sat, 12 Apr 2025 12:13:12 -0700 Subject: [PATCH 02/24] Remove storeAuthStateInCookie --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 - lib/msal-angular/docs/configuration.md | 3 - lib/msal-angular/docs/events.md | 1 - lib/msal-angular/docs/initialization.md | 2 - lib/msal-browser/docs/configuration.md | 2 - .../src/cache/BrowserCacheManager.ts | 30 -- lib/msal-browser/src/config/Configuration.ts | 5 - .../src/controllers/StandardController.ts | 1 - .../error/BrowserConfigurationAuthError.ts | 2 +- lib/msal-browser/src/utils/BrowserUtils.ts | 5 +- .../test/app/PublicClientApplication.spec.ts | 5 +- .../test/cache/BrowserCacheManager.spec.ts | 313 ------------------ .../test/cache/TokenCache.spec.ts | 1 - .../test/config/Configuration.spec.ts | 5 - .../interaction_client/RedirectClient.spec.ts | 1 - .../authConfigs/aadAuthConfig.json | 9 +- .../authConfigs/aadMultiTenantAuthConfig.json | 13 +- .../authConfigs/aadTenantedAuthConfig.json | 9 +- .../authConfigs/b2cAuthConfig.json | 13 +- .../authConfigs/localStorageAuthConfig.json | 9 +- .../authConfigs/memStorageAuthConfig.json | 9 +- .../react-router-sample/README.md | 4 - 22 files changed, 39 insertions(+), 404 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 8ee6733c52..c1eebb8ecd 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -109,7 +109,6 @@ body: }, cache: { cacheLocation: "sessionStorage" - storeAuthStateInCookie: false } } validations: diff --git a/lib/msal-angular/docs/configuration.md b/lib/msal-angular/docs/configuration.md index 0468194f93..f7d8e10102 100644 --- a/lib/msal-angular/docs/configuration.md +++ b/lib/msal-angular/docs/configuration.md @@ -58,7 +58,6 @@ import { PublicClientApplication, InteractionType, BrowserCacheLocation } from " }, cache: { cacheLocation: BrowserCacheLocation.LocalStorage, - storeAuthStateInCookie: true, // set to true for IE 11 }, system: { loggerOptions: { @@ -261,7 +260,6 @@ fetch("/assets/configuration.json") }, "cache": { "cacheLocation": "localStorage", - "storeAuthStateInCookie": true } }, "guard": { @@ -471,7 +469,6 @@ export class AppModule {} }, "cache": { "cacheLocation": "localStorage", - "storeAuthStateInCookie": true } }, "guard": { diff --git a/lib/msal-angular/docs/events.md b/lib/msal-angular/docs/events.md index 91ea4b0ec0..5995c8a07e 100644 --- a/lib/msal-angular/docs/events.md +++ b/lib/msal-angular/docs/events.md @@ -222,7 +222,6 @@ import { PublicClientApplication, InteractionType, BrowserCacheLocation } from " }, cache: { cacheLocation : BrowserCacheLocation.LocalStorage, - storeAuthStateInCookie: true, // set to true for IE 11 }, system: { loggerOptions: { diff --git a/lib/msal-angular/docs/initialization.md b/lib/msal-angular/docs/initialization.md index a8b2f7e1e7..4712b69130 100644 --- a/lib/msal-angular/docs/initialization.md +++ b/lib/msal-angular/docs/initialization.md @@ -31,7 +31,6 @@ import { PublicClientApplication, InteractionType, BrowserCacheLocation } from " }, cache: { cacheLocation : BrowserCacheLocation.LocalStorage, - storeAuthStateInCookie: true, // set to true for IE 11 }, system: { loggerOptions: { @@ -115,7 +114,6 @@ import { PublicClientApplication, InteractionType, BrowserCacheLocation } from " }, cache: { cacheLocation : BrowserCacheLocation.LocalStorage, - storeAuthStateInCookie: true, // set to true for IE 11 }, system: { loggerOptions: { diff --git a/lib/msal-browser/docs/configuration.md b/lib/msal-browser/docs/configuration.md index 62dda1c2fc..f726e94786 100644 --- a/lib/msal-browser/docs/configuration.md +++ b/lib/msal-browser/docs/configuration.md @@ -24,7 +24,6 @@ const msalConfig = { cache: { cacheLocation: "sessionStorage", temporaryCacheLocation: "sessionStorage", - storeAuthStateInCookie: false, secureCookies: false, claimsBasedCachingEnabled: true, }, @@ -98,7 +97,6 @@ const msalInstance = new PublicClientApplication(msalConfig); | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | | `cacheLocation` | Location of token cache in browser. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | | `temporaryCacheLocation` | Location of temporary cache in browser. This option should only be changed for specific edge cases. Please refer to [caching](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/caching.md#cached-artifacts) for more. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | -| `storeAuthStateInCookie` | If true, stores cache items in cookies as well as browser cache. Should be set to true for use cases using IE. | boolean | `false` | | `secureCookies` | If true and `storeAuthStateInCookies` is also enabled, MSAL adds the `Secure` flag to the browser cookie so it can only be sent over HTTPS. | boolean | `false` | | `cacheMigrationEnabled` | If true, cache entries from older versions of MSAL will be updated to conform to the latest cache schema on startup. If your application has not been recently updated to a new version of MSAL.js you can safely turn this off. In the event old cache entries are not migrated it may result in a cache miss when attempting to retrieve accounts or tokens and affected users may need to re-authenticate to get up to date. | boolean | `true` when using `localStorage`, `false` otherwise | | `claimsBasedCachingEnabled` | If `true`, access tokens will be cached under a key containing the hash of the requested claims string, resulting in a cache miss and new network token request when the same token request is made with different or missing claims. If set to `false`, tokens will be cached without claims, but all requests containing claims will go to the network and overwrite any previously cached token with the same scopes. | boolean | `false` | diff --git a/lib/msal-browser/src/cache/BrowserCacheManager.ts b/lib/msal-browser/src/cache/BrowserCacheManager.ts index 4bedbdc870..4c67d29a23 100644 --- a/lib/msal-browser/src/cache/BrowserCacheManager.ts +++ b/lib/msal-browser/src/cache/BrowserCacheManager.ts @@ -68,8 +68,6 @@ import { EventHandler } from "../event/EventHandler.js"; /** * This class implements the cache storage interface for MSAL through browser local or session storage. - * Cookies are only used if storeAuthStateInCookie is true, and are only used for - * parameters such as state and nonce, generally. */ export class BrowserCacheManager extends CacheManager { // Cache configuration, either set by user or default values. @@ -885,21 +883,10 @@ export class BrowserCacheManager extends CacheManager { /** * Gets cache item with given key. - * Will retrieve from cookies if storeAuthStateInCookie is set to true. * @param key */ getTemporaryCache(cacheKey: string, generateKey?: boolean): string | null { const key = generateKey ? this.generateCacheKey(cacheKey) : cacheKey; - if (this.cacheConfig.storeAuthStateInCookie) { - const itemCookie = this.cookieStorage.getItem(key); - if (itemCookie) { - this.logger.trace( - "BrowserCacheManager.getTemporaryCache: storeAuthStateInCookies set to true, retrieving from cookies" - ); - return itemCookie; - } - } - const value = this.temporaryCacheStorage.getItem(key); if (!value) { // If temp cache item not found in session/memory, check local storage for items set by old versions @@ -928,8 +915,6 @@ export class BrowserCacheManager extends CacheManager { /** * Sets the cache item with the key and value given. - * Stores in cookie if storeAuthStateInCookie is set to true. - * This can cause cookie overflow if used incorrectly. * @param key * @param value */ @@ -939,14 +924,7 @@ export class BrowserCacheManager extends CacheManager { generateKey?: boolean ): void { const key = generateKey ? this.generateCacheKey(cacheKey) : cacheKey; - this.temporaryCacheStorage.setItem(key, value); - if (this.cacheConfig.storeAuthStateInCookie) { - this.logger.trace( - "BrowserCacheManager.setTemporaryCache: storeAuthStateInCookie set to true, setting item cookie" - ); - this.cookieStorage.setItem(key, value, undefined); - } } /** @@ -959,17 +937,10 @@ export class BrowserCacheManager extends CacheManager { /** * Removes the temporary cache item with the given key. - * Will also clear the cookie item if storeAuthStateInCookie is set to true. * @param key */ removeTemporaryItem(key: string): void { this.temporaryCacheStorage.removeItem(key); - if (this.cacheConfig.storeAuthStateInCookie) { - this.logger.trace( - "BrowserCacheManager.removeItem: storeAuthStateInCookie is true, clearing item cookie" - ); - this.cookieStorage.removeItem(key); - } } /** @@ -1370,7 +1341,6 @@ export const DEFAULT_BROWSER_CACHE_MANAGER = ( const cacheOptions: Required = { cacheLocation: BrowserCacheLocation.MemoryStorage, temporaryCacheLocation: BrowserCacheLocation.MemoryStorage, - storeAuthStateInCookie: false, cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; diff --git a/lib/msal-browser/src/config/Configuration.ts b/lib/msal-browser/src/config/Configuration.ts index e04e7b98a5..a622c448b3 100644 --- a/lib/msal-browser/src/config/Configuration.ts +++ b/lib/msal-browser/src/config/Configuration.ts @@ -127,10 +127,6 @@ export type CacheOptions = { * Used to specify the temporaryCacheLocation user wants to set. Valid values are "localStorage", "sessionStorage" and "memoryStorage". */ temporaryCacheLocation?: BrowserCacheLocation | string; - /** - * If set, MSAL stores the auth request state required for validation of the auth flows in the browser cookies. By default this flag is set to false. - */ - storeAuthStateInCookie?: boolean; /** * If set, MSAL will attempt to migrate cache entries from older versions on initialization. By default this flag is set to true if cacheLocation is localStorage, otherwise false. */ @@ -287,7 +283,6 @@ export function buildConfiguration( const DEFAULT_CACHE_OPTIONS: Required = { cacheLocation: BrowserCacheLocation.SessionStorage, temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, // Default cache migration to true if cache location is localStorage since entries are preserved across tabs/windows. Migration has little to no benefit in sessionStorage and memoryStorage cacheMigrationEnabled: userInputCache && diff --git a/lib/msal-browser/src/controllers/StandardController.ts b/lib/msal-browser/src/controllers/StandardController.ts index 18067bf4e7..ced406fb50 100644 --- a/lib/msal-browser/src/controllers/StandardController.ts +++ b/lib/msal-browser/src/controllers/StandardController.ts @@ -257,7 +257,6 @@ export class StandardController implements IController { const nativeCacheOptions: Required = { cacheLocation: BrowserCacheLocation.MemoryStorage, temporaryCacheLocation: BrowserCacheLocation.MemoryStorage, - storeAuthStateInCookie: false, cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; diff --git a/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts b/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts index 1550fa0c51..c6185f0c6a 100644 --- a/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts +++ b/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts @@ -13,7 +13,7 @@ export const BrowserConfigurationAuthErrorMessages = { [BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled]: "Stub instance of Public Client Application was called. If using msal-react, please ensure context is not used without a provider. For more visit: aka.ms/msaljs/browser-errors", [BrowserConfigurationAuthErrorCodes.inMemRedirectUnavailable]: - "Redirect cannot be supported. In-memory storage was selected and storeAuthStateInCookie=false, which would cause the library to be unable to handle the incoming hash. If you would like to use the redirect API, please use session/localStorage or set storeAuthStateInCookie=true.", + "Redirect cannot be supported. In-memory storage was selected, which would cause the library to be unable to handle the incoming hash. If you would like to use the redirect API, please use session/localStorage.", }; /** diff --git a/lib/msal-browser/src/utils/BrowserUtils.ts b/lib/msal-browser/src/utils/BrowserUtils.ts index b1e1c9b5bd..02825ae3e7 100644 --- a/lib/msal-browser/src/utils/BrowserUtils.ts +++ b/lib/msal-browser/src/utils/BrowserUtils.ts @@ -171,10 +171,9 @@ export function redirectPreflightCheck( ): void { preflightCheck(initialized); blockRedirectInIframe(config.system.allowRedirectInIframe); - // Block redirects if memory storage is enabled but storeAuthStateInCookie is not + // Block redirects if memory storage is enabled if ( - config.cache.cacheLocation === BrowserCacheLocation.MemoryStorage && - !config.cache.storeAuthStateInCookie + config.cache.cacheLocation === BrowserCacheLocation.MemoryStorage ) { throw createBrowserConfigurationAuthError( BrowserConfigurationAuthErrorCodes.inMemRedirectUnavailable diff --git a/lib/msal-browser/test/app/PublicClientApplication.spec.ts b/lib/msal-browser/test/app/PublicClientApplication.spec.ts index 97e511ec42..2bebc833f5 100644 --- a/lib/msal-browser/test/app/PublicClientApplication.spec.ts +++ b/lib/msal-browser/test/app/PublicClientApplication.spec.ts @@ -119,7 +119,6 @@ import { INTERACTION_TYPE } from "../../src/utils/BrowserConstants.js"; const cacheConfig = { temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; @@ -1933,14 +1932,13 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { } }); - it("throws error if cacheLocation is Memory Storage and storeAuthStateInCookie is false", async () => { + it("throws error if cacheLocation is Memory Storage", async () => { pca = new PublicClientApplication({ auth: { clientId: TEST_CONFIG.MSAL_CLIENT_ID, }, cache: { cacheLocation: BrowserCacheLocation.MemoryStorage, - storeAuthStateInCookie: false, }, system: { allowPlatformBroker: false, @@ -7281,7 +7279,6 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { { cacheLocation: BrowserCacheLocation.LocalStorage, temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }, diff --git a/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts b/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts index a732e886d0..7602e877c9 100644 --- a/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts +++ b/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts @@ -61,7 +61,6 @@ describe("BrowserCacheManager tests", () => { cacheConfig = { temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; @@ -2378,318 +2377,6 @@ describe("BrowserCacheManager tests", () => { }); }); - describe("Interface functions with storeAuthStateInCookie=true", () => { - let browserSessionStorage: BrowserCacheManager; - let browserLocalStorage: BrowserCacheManager; - let browserMemoryStorage: BrowserCacheManager; - let cacheVal: string; - let msalCacheKey: string; - beforeEach(async () => { - browserSessionStorage = new BrowserCacheManager( - TEST_CONFIG.MSAL_CLIENT_ID, - { - ...cacheConfig, - cacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: true, - }, - browserCrypto, - logger, - new StubPerformanceClient(), - new EventHandler() - ); - await browserSessionStorage.initialize(TEST_CONFIG.CORRELATION_ID); - browserLocalStorage = new BrowserCacheManager( - TEST_CONFIG.MSAL_CLIENT_ID, - { - ...cacheConfig, - cacheLocation: BrowserCacheLocation.LocalStorage, - storeAuthStateInCookie: true, - }, - browserCrypto, - logger, - new StubPerformanceClient(), - new EventHandler() - ); - await browserLocalStorage.initialize(TEST_CONFIG.CORRELATION_ID); - browserMemoryStorage = new BrowserCacheManager( - TEST_CONFIG.MSAL_CLIENT_ID, - { - ...cacheConfig, - cacheLocation: BrowserCacheLocation.MemoryStorage, - storeAuthStateInCookie: true, - }, - browserCrypto, - logger, - new StubPerformanceClient(), - new EventHandler() - ); - await browserMemoryStorage.initialize(TEST_CONFIG.CORRELATION_ID); - cacheVal = "cacheVal"; - msalCacheKey = browserSessionStorage.generateCacheKey("cacheKey"); - }); - - afterEach(async () => { - await browserSessionStorage.clear(); - await browserLocalStorage.clear(); - }); - - it("setTempCache()", () => { - // sessionStorage - browserSessionStorage.setTemporaryCache( - msalCacheKey, - cacheVal, - true - ); - expect(window.sessionStorage.getItem(msalCacheKey)).toBe(cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - // @ts-ignore - browserSessionStorage.cookieStorage.removeItem(msalCacheKey); - // localStorage - browserLocalStorage.setTemporaryCache(msalCacheKey, cacheVal, true); - expect(window.sessionStorage.getItem(msalCacheKey)).toBe(cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - // @ts-ignore - browserLocalStorage.cookieStorage.removeItem(msalCacheKey); - // browser memory - browserMemoryStorage.setTemporaryCache( - msalCacheKey, - cacheVal, - true - ); - expect(browserMemoryStorage.getTemporaryCache(msalCacheKey)).toBe( - cacheVal - ); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - // @ts-ignore - browserMemoryStorage.cookieStorage.removeItem(msalCacheKey); - }); - - it("getTempCache()", () => { - // sessionStorage - browserSessionStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect( - browserSessionStorage.getTemporaryCache(msalCacheKey, true) - ).toBe(cacheVal); - expect( - // @ts-ignore - browserSessionStorage.cookieStorage.getItem(msalCacheKey) - ).toEqual(cacheVal); - // localStorage - browserLocalStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect( - browserLocalStorage.getTemporaryCache(msalCacheKey, true) - ).toBe(cacheVal); - expect( - // @ts-ignore - browserLocalStorage.cookieStorage.getItem(msalCacheKey) - ).toEqual(cacheVal); - // @ts-ignore - browserMemoryStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect( - browserMemoryStorage.getTemporaryCache(msalCacheKey, true) - ).toBe(cacheVal); - expect( - // @ts-ignore - browserMemoryStorage.cookieStorage.getItem(msalCacheKey) - ).toEqual(cacheVal); - }); - - it("removeTemporaryItem()", () => { - const clearCookieSpy = jest.spyOn( - CookieStorage.prototype, - "removeItem" - ); - // sessionStorage - browserSessionStorage.setTemporaryCache( - msalCacheKey, - cacheVal, - true - ); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - browserSessionStorage.removeTemporaryItem(msalCacheKey); - expect(window.sessionStorage.getItem(msalCacheKey)).toBeNull(); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - expect(clearCookieSpy).toHaveBeenCalledTimes(1); - // localStorage - browserLocalStorage.setTemporaryCache(msalCacheKey, cacheVal, true); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - browserLocalStorage.removeTemporaryItem(msalCacheKey); - expect(window.localStorage.getItem(msalCacheKey)).toBeNull(); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - expect(clearCookieSpy).toHaveBeenCalledTimes(2); - // browser memory - browserMemoryStorage.setTemporaryCache( - msalCacheKey, - cacheVal, - true - ); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - browserMemoryStorage.removeTemporaryItem(msalCacheKey); - expect( - // @ts-ignore - browserMemoryStorage.temporaryCacheStorage.getItem(msalCacheKey) - ).toBeNull(); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - expect(clearCookieSpy).toHaveBeenCalledTimes(3); - }); - - it("clear()", async () => { - // sessionStorage - browserSessionStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - await browserSessionStorage.clear(); - expect(browserSessionStorage.getKeys()).toHaveLength(0); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - // localStorage - browserLocalStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - await browserLocalStorage.clear(); - expect(browserLocalStorage.getKeys()).toHaveLength(0); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - // browser memory - browserMemoryStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - await browserMemoryStorage.clear(); - expect(browserMemoryStorage.getKeys()).toHaveLength(0); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - }); - - it("setTempCache() with item that contains ==", () => { - msalCacheKey = `${Constants.CACHE_PREFIX}.${TEST_STATE_VALUES.ENCODED_LIB_STATE}`; - // sessionStorage - browserSessionStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(window.sessionStorage.getItem(msalCacheKey)).toBe(cacheVal); - expect(document.cookie).toContain( - `${encodeURIComponent(msalCacheKey)}=${cacheVal}` - ); - // @ts-ignore - browserSessionStorage.cookieStorage.removeItem(msalCacheKey); - // localStorage - browserLocalStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(window.sessionStorage.getItem(msalCacheKey)).toBe(cacheVal); - expect(document.cookie).toContain( - `${encodeURIComponent(msalCacheKey)}=${cacheVal}` - ); - // @ts-ignore - browserLocalStorage.cookieStorage.removeItem(msalCacheKey); - // browser memory - browserMemoryStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(browserMemoryStorage.getTemporaryCache(msalCacheKey)).toBe( - cacheVal - ); - expect(document.cookie).toContain( - `${encodeURIComponent(msalCacheKey)}=${cacheVal}` - ); - // @ts-ignore - browserMemoryStorage.cookieStorage.removeItem(msalCacheKey); - }); - - it("getTempCache() with item that contains ==", () => { - msalCacheKey = `${Constants.CACHE_PREFIX}.${TEST_STATE_VALUES.ENCODED_LIB_STATE}`; - const getCookieSpy = jest.spyOn(CookieStorage.prototype, "getItem"); - // sessionStorage - browserSessionStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(browserSessionStorage.getTemporaryCache(msalCacheKey)).toBe( - cacheVal - ); - expect(getCookieSpy.mock.results[0].value).toEqual(cacheVal); - expect(getCookieSpy).toHaveBeenCalledTimes(1); - // localStorage - browserLocalStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(browserLocalStorage.getTemporaryCache(msalCacheKey)).toBe( - cacheVal - ); - expect(getCookieSpy.mock.results[1].value).toEqual(cacheVal); - expect(getCookieSpy).toHaveBeenCalledTimes(2); - // @ts-ignore - browserMemoryStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(browserLocalStorage.getTemporaryCache(msalCacheKey)).toBe( - cacheVal - ); - expect(getCookieSpy.mock.results[2].value).toEqual(cacheVal); - expect(getCookieSpy).toHaveBeenCalledTimes(3); - }); - - it("removeTemporaryItem() with item that contains ==", () => { - msalCacheKey = `${Constants.CACHE_PREFIX}.${TEST_STATE_VALUES.ENCODED_LIB_STATE}`; - const clearCookieSpy = jest.spyOn( - CookieStorage.prototype, - "removeItem" - ); - // sessionStorage - browserSessionStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(window.sessionStorage.getItem(msalCacheKey)).toBe(cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - browserSessionStorage.removeTemporaryItem(msalCacheKey); - expect(window.sessionStorage.getItem(msalCacheKey)).toBeNull(); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - expect(clearCookieSpy).toHaveBeenCalledTimes(1); - // localStorage - browserLocalStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - browserLocalStorage.removeTemporaryItem(msalCacheKey); - expect(window.sessionStorage.getItem(msalCacheKey)).toBeNull(); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - expect(clearCookieSpy).toHaveBeenCalledTimes(2); - // browser memory - browserMemoryStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - browserMemoryStorage.removeTemporaryItem(msalCacheKey); - // @ts-ignore - expect( - browserMemoryStorage.getTemporaryCache(msalCacheKey) - ).toBeNull(); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - expect(clearCookieSpy).toHaveBeenCalledTimes(3); - }); - - it("clear() with item that contains ==", async () => { - msalCacheKey = `${Constants.CACHE_PREFIX}.${TEST_STATE_VALUES.ENCODED_LIB_STATE}`; - // sessionStorage - browserSessionStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - await browserSessionStorage.clear(); - expect(browserSessionStorage.getKeys()).toHaveLength(0); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - // localStorage - browserLocalStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - await browserLocalStorage.clear(); - expect(browserLocalStorage.getKeys()).toHaveLength(0); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - // browser memory - browserMemoryStorage.setTemporaryCache(msalCacheKey, cacheVal); - expect(document.cookie).toContain(`${msalCacheKey}=${cacheVal}`); - await browserMemoryStorage.clear(); - expect(browserMemoryStorage.getKeys()).toHaveLength(0); - expect(document.cookie).not.toContain( - `${msalCacheKey}=${cacheVal}` - ); - }); - }); - describe("Helpers", () => { it("resetTempCacheItems() resets all temporary cache items with the given state", () => { const browserStorage = new BrowserCacheManager( diff --git a/lib/msal-browser/test/cache/TokenCache.spec.ts b/lib/msal-browser/test/cache/TokenCache.spec.ts index 7a262f9462..9b37b3265a 100644 --- a/lib/msal-browser/test/cache/TokenCache.spec.ts +++ b/lib/msal-browser/test/cache/TokenCache.spec.ts @@ -64,7 +64,6 @@ describe("TokenCache tests", () => { cacheConfig = { temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; diff --git a/lib/msal-browser/test/config/Configuration.spec.ts b/lib/msal-browser/test/config/Configuration.spec.ts index 93b437d55f..e083372b94 100644 --- a/lib/msal-browser/test/config/Configuration.spec.ts +++ b/lib/msal-browser/test/config/Configuration.spec.ts @@ -52,8 +52,6 @@ describe("Configuration.ts Class Unit Tests", () => { expect(emptyConfig.cache).toBeDefined(); expect(emptyConfig.cache?.cacheLocation).toBeDefined(); expect(emptyConfig.cache?.cacheLocation).toBe("sessionStorage"); - expect(emptyConfig.cache?.storeAuthStateInCookie).toBeDefined(); - expect(emptyConfig.cache?.storeAuthStateInCookie).toBe(false); expect(emptyConfig.cache?.claimsBasedCachingEnabled).toBe(false); // System config checks expect(emptyConfig.system).toBeDefined(); @@ -242,7 +240,6 @@ describe("Configuration.ts Class Unit Tests", () => { }, cache: { cacheLocation: BrowserCacheLocation.LocalStorage, - storeAuthStateInCookie: true, claimsBasedCachingEnabled: true, }, system: { @@ -272,8 +269,6 @@ describe("Configuration.ts Class Unit Tests", () => { expect(newConfig.cache).not.toBeNull(); expect(newConfig.cache?.cacheLocation).not.toBeNull(); expect(newConfig.cache?.cacheLocation).toBe("localStorage"); - expect(newConfig.cache?.storeAuthStateInCookie).not.toBeNull(); - expect(newConfig.cache?.storeAuthStateInCookie).toBe(true); expect(newConfig.cache?.claimsBasedCachingEnabled).toBe(true); // System config checks expect(newConfig.system).not.toBeNull(); diff --git a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts index 43711e5bf6..70af23cb34 100644 --- a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts +++ b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts @@ -91,7 +91,6 @@ import { BrowserPerformanceClient } from "../../src/telemetry/BrowserPerformance const cacheConfig = { cacheLocation: BrowserCacheLocation.SessionStorage, temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; diff --git a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadAuthConfig.json b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadAuthConfig.json index 90ec1944b5..5c7795cd33 100644 --- a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadAuthConfig.json +++ b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadAuthConfig.json @@ -5,14 +5,15 @@ "authority": "https://login.microsoftonline.com/common" }, "cache": { - "cacheLocation": "sessionStorage", - "storeAuthStateInCookie": false + "cacheLocation": "sessionStorage" }, "system": { "allowPlatformBroker": false } }, "request": { - "scopes": ["User.Read"] + "scopes": [ + "User.Read" + ] } -} +} \ No newline at end of file diff --git a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadMultiTenantAuthConfig.json b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadMultiTenantAuthConfig.json index 5b8a7aec68..c63d83c02c 100644 --- a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadMultiTenantAuthConfig.json +++ b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadMultiTenantAuthConfig.json @@ -5,24 +5,25 @@ "authority": "https://login.microsoftonline.com/f645ad92-e38d-4d1a-b510-d1b09a74a8ca" }, "cache": { - "cacheLocation": "sessionStorage", - "storeAuthStateInCookie": false + "cacheLocation": "sessionStorage" }, "system": { "allowPlatformBroker": false } }, "request": { - "scopes": ["User.Read"] + "scopes": [ + "User.Read" + ] }, "tenants": { - "home": { + "home": { "tenantId": "f645ad92-e38d-4d1a-b510-d1b09a74a8ca", "authority": "https://login.microsoftonline.com/f645ad92-e38d-4d1a-b510-d1b09a74a8ca" - }, + }, "guest": { "tenantId": "8e44f19d-bbab-4a82-b76b-4cd0a6fbc97a", "authority": "https://login.microsoftonline.com/8e44f19d-bbab-4a82-b76b-4cd0a6fbc97a" } } -} +} \ No newline at end of file diff --git a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadTenantedAuthConfig.json b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadTenantedAuthConfig.json index 01141aec79..bd2a17cd71 100644 --- a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadTenantedAuthConfig.json +++ b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/aadTenantedAuthConfig.json @@ -5,14 +5,15 @@ "authority": "https://login.microsoftonline.com/f645ad92-e38d-4d1a-b510-d1b09a74a8ca" }, "cache": { - "cacheLocation": "sessionStorage", - "storeAuthStateInCookie": false + "cacheLocation": "sessionStorage" }, "system": { "allowPlatformBroker": false } }, "request": { - "scopes": ["User.Read"] + "scopes": [ + "User.Read" + ] } -} +} \ No newline at end of file diff --git a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/b2cAuthConfig.json b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/b2cAuthConfig.json index e7755bd5d0..5eb872a9bc 100644 --- a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/b2cAuthConfig.json +++ b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/b2cAuthConfig.json @@ -3,17 +3,20 @@ "auth": { "clientId": "4c837770-7a2b-471e-aafa-3328d04a23b1", "authority": "https://msidlabb2c.b2clogin.com/msidlabb2c.onmicrosoft.com/B2C_1_SISOPolicy/", - "knownAuthorities": ["msidlabb2c.b2clogin.com"] + "knownAuthorities": [ + "msidlabb2c.b2clogin.com" + ] }, "cache": { - "cacheLocation": "sessionStorage", - "storeAuthStateInCookie": false + "cacheLocation": "sessionStorage" }, "system": { "allowPlatformBroker": false } }, "request": { - "scopes": ["https://msidlabb2c.onmicrosoft.com/4c837770-7a2b-471e-aafa-3328d04a23b1/read"] + "scopes": [ + "https://msidlabb2c.onmicrosoft.com/4c837770-7a2b-471e-aafa-3328d04a23b1/read" + ] } -} +} \ No newline at end of file diff --git a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/localStorageAuthConfig.json b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/localStorageAuthConfig.json index 42e38744a0..07338ec644 100644 --- a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/localStorageAuthConfig.json +++ b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/localStorageAuthConfig.json @@ -5,14 +5,15 @@ "authority": "https://login.microsoftonline.com/common" }, "cache": { - "cacheLocation": "localStorage", - "storeAuthStateInCookie": false + "cacheLocation": "localStorage" }, "system": { "allowPlatformBroker": false } }, "request": { - "scopes": ["User.Read"] + "scopes": [ + "User.Read" + ] } -} +} \ No newline at end of file diff --git a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/memStorageAuthConfig.json b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/memStorageAuthConfig.json index 580be73a47..eb120a7590 100644 --- a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/memStorageAuthConfig.json +++ b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/authConfigs/memStorageAuthConfig.json @@ -5,14 +5,15 @@ "authority": "https://login.microsoftonline.com/common" }, "cache": { - "cacheLocation": "memoryStorage", - "storeAuthStateInCookie": true + "cacheLocation": "memoryStorage" }, "system": { "allowPlatformBroker": false } }, "request": { - "scopes": ["User.Read"] + "scopes": [ + "User.Read" + ] } -} +} \ No newline at end of file diff --git a/samples/msal-react-samples/react-router-sample/README.md b/samples/msal-react-samples/react-router-sample/README.md index f409c90c62..3d51fc313a 100644 --- a/samples/msal-react-samples/react-router-sample/README.md +++ b/samples/msal-react-samples/react-router-sample/README.md @@ -80,10 +80,6 @@ You will also see any lint errors in the console. 1. Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 1. Open [http://localhost:3000/profile](http://localhost:3000/profile) to see an example of a protected route. If you are not yet signed in, signin will be invoked automatically. -#### Running the sample in IE11 - -`@azure/msal-react` and `@azure/msal-browser` support IE11 but the `react-scripts` package requires a few polyfills to work properly. In order to run this sample in IE11 go to `src/index.js` and uncomment the first 2 imports. We recommend using the redirect flow and setting the `storeAuthStateInCookie` config parameter to `true` in IE11 as there are known issues with popups. You can read more about the known issues with IE11 [here](https://github.com/AzureAD/microsoft-authentication-library-for-js/wiki/Known-issues-on-IE-and-Edge-Browser) - #### Learn more about the 3rd-party libraries used to create this sample - [React documentation](https://reactjs.org/). From 9ecf558d7dbd8c6f2f4486eca07858c315265db5 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Sat, 12 Apr 2025 12:18:11 -0700 Subject: [PATCH 03/24] Remove secureCookies docs --- lib/msal-browser/docs/configuration.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/msal-browser/docs/configuration.md b/lib/msal-browser/docs/configuration.md index f726e94786..699e38d137 100644 --- a/lib/msal-browser/docs/configuration.md +++ b/lib/msal-browser/docs/configuration.md @@ -24,7 +24,6 @@ const msalConfig = { cache: { cacheLocation: "sessionStorage", temporaryCacheLocation: "sessionStorage", - secureCookies: false, claimsBasedCachingEnabled: true, }, system: { @@ -97,7 +96,6 @@ const msalInstance = new PublicClientApplication(msalConfig); | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | | `cacheLocation` | Location of token cache in browser. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | | `temporaryCacheLocation` | Location of temporary cache in browser. This option should only be changed for specific edge cases. Please refer to [caching](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/caching.md#cached-artifacts) for more. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | -| `secureCookies` | If true and `storeAuthStateInCookies` is also enabled, MSAL adds the `Secure` flag to the browser cookie so it can only be sent over HTTPS. | boolean | `false` | | `cacheMigrationEnabled` | If true, cache entries from older versions of MSAL will be updated to conform to the latest cache schema on startup. If your application has not been recently updated to a new version of MSAL.js you can safely turn this off. In the event old cache entries are not migrated it may result in a cache miss when attempting to retrieve accounts or tokens and affected users may need to re-authenticate to get up to date. | boolean | `true` when using `localStorage`, `false` otherwise | | `claimsBasedCachingEnabled` | If `true`, access tokens will be cached under a key containing the hash of the requested claims string, resulting in a cache miss and new network token request when the same token request is made with different or missing claims. If set to `false`, tokens will be cached without claims, but all requests containing claims will go to the network and overwrite any previously cached token with the same scopes. | boolean | `false` | From 279d602bee0db813fcb9ff824ec3a4948b3e99fe Mon Sep 17 00:00:00 2001 From: joarroyo Date: Sat, 12 Apr 2025 12:27:10 -0700 Subject: [PATCH 04/24] Remove cacheMigrationEnabled --- lib/msal-browser/docs/configuration.md | 1 - lib/msal-browser/src/cache/BrowserCacheManager.ts | 1 - lib/msal-browser/src/config/Configuration.ts | 10 ---------- lib/msal-browser/src/controllers/StandardController.ts | 1 - .../test/app/PublicClientApplication.spec.ts | 2 -- .../test/cache/BrowserCacheManager.spec.ts | 1 - lib/msal-browser/test/cache/TokenCache.spec.ts | 1 - .../test/interaction_client/RedirectClient.spec.ts | 1 - 8 files changed, 18 deletions(-) diff --git a/lib/msal-browser/docs/configuration.md b/lib/msal-browser/docs/configuration.md index 699e38d137..10583cbc09 100644 --- a/lib/msal-browser/docs/configuration.md +++ b/lib/msal-browser/docs/configuration.md @@ -96,7 +96,6 @@ const msalInstance = new PublicClientApplication(msalConfig); | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | | `cacheLocation` | Location of token cache in browser. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | | `temporaryCacheLocation` | Location of temporary cache in browser. This option should only be changed for specific edge cases. Please refer to [caching](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/caching.md#cached-artifacts) for more. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | -| `cacheMigrationEnabled` | If true, cache entries from older versions of MSAL will be updated to conform to the latest cache schema on startup. If your application has not been recently updated to a new version of MSAL.js you can safely turn this off. In the event old cache entries are not migrated it may result in a cache miss when attempting to retrieve accounts or tokens and affected users may need to re-authenticate to get up to date. | boolean | `true` when using `localStorage`, `false` otherwise | | `claimsBasedCachingEnabled` | If `true`, access tokens will be cached under a key containing the hash of the requested claims string, resulting in a cache miss and new network token request when the same token request is made with different or missing claims. If set to `false`, tokens will be cached without claims, but all requests containing claims will go to the network and overwrite any previously cached token with the same scopes. | boolean | `false` | See [Caching in MSAL](./caching.md) for more. diff --git a/lib/msal-browser/src/cache/BrowserCacheManager.ts b/lib/msal-browser/src/cache/BrowserCacheManager.ts index 4c67d29a23..c2a59f32d9 100644 --- a/lib/msal-browser/src/cache/BrowserCacheManager.ts +++ b/lib/msal-browser/src/cache/BrowserCacheManager.ts @@ -1341,7 +1341,6 @@ export const DEFAULT_BROWSER_CACHE_MANAGER = ( const cacheOptions: Required = { cacheLocation: BrowserCacheLocation.MemoryStorage, temporaryCacheLocation: BrowserCacheLocation.MemoryStorage, - cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; return new BrowserCacheManager( diff --git a/lib/msal-browser/src/config/Configuration.ts b/lib/msal-browser/src/config/Configuration.ts index a622c448b3..ae49e43d59 100644 --- a/lib/msal-browser/src/config/Configuration.ts +++ b/lib/msal-browser/src/config/Configuration.ts @@ -127,10 +127,6 @@ export type CacheOptions = { * Used to specify the temporaryCacheLocation user wants to set. Valid values are "localStorage", "sessionStorage" and "memoryStorage". */ temporaryCacheLocation?: BrowserCacheLocation | string; - /** - * If set, MSAL will attempt to migrate cache entries from older versions on initialization. By default this flag is set to true if cacheLocation is localStorage, otherwise false. - */ - cacheMigrationEnabled?: boolean; /** * Flag that determines whether access tokens are stored based on requested claims */ @@ -283,12 +279,6 @@ export function buildConfiguration( const DEFAULT_CACHE_OPTIONS: Required = { cacheLocation: BrowserCacheLocation.SessionStorage, temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - // Default cache migration to true if cache location is localStorage since entries are preserved across tabs/windows. Migration has little to no benefit in sessionStorage and memoryStorage - cacheMigrationEnabled: - userInputCache && - userInputCache.cacheLocation === BrowserCacheLocation.LocalStorage - ? true - : false, claimsBasedCachingEnabled: false, }; diff --git a/lib/msal-browser/src/controllers/StandardController.ts b/lib/msal-browser/src/controllers/StandardController.ts index ced406fb50..de1ddbe8e8 100644 --- a/lib/msal-browser/src/controllers/StandardController.ts +++ b/lib/msal-browser/src/controllers/StandardController.ts @@ -257,7 +257,6 @@ export class StandardController implements IController { const nativeCacheOptions: Required = { cacheLocation: BrowserCacheLocation.MemoryStorage, temporaryCacheLocation: BrowserCacheLocation.MemoryStorage, - cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; this.nativeInternalStorage = new BrowserCacheManager( diff --git a/lib/msal-browser/test/app/PublicClientApplication.spec.ts b/lib/msal-browser/test/app/PublicClientApplication.spec.ts index 2bebc833f5..e94844074c 100644 --- a/lib/msal-browser/test/app/PublicClientApplication.spec.ts +++ b/lib/msal-browser/test/app/PublicClientApplication.spec.ts @@ -119,7 +119,6 @@ import { INTERACTION_TYPE } from "../../src/utils/BrowserConstants.js"; const cacheConfig = { temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; @@ -7279,7 +7278,6 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { { cacheLocation: BrowserCacheLocation.LocalStorage, temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }, new CryptoOps(new Logger({})), diff --git a/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts b/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts index 7602e877c9..a85afd7f15 100644 --- a/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts +++ b/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts @@ -61,7 +61,6 @@ describe("BrowserCacheManager tests", () => { cacheConfig = { temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; logger = new Logger({ diff --git a/lib/msal-browser/test/cache/TokenCache.spec.ts b/lib/msal-browser/test/cache/TokenCache.spec.ts index 9b37b3265a..19e507594a 100644 --- a/lib/msal-browser/test/cache/TokenCache.spec.ts +++ b/lib/msal-browser/test/cache/TokenCache.spec.ts @@ -64,7 +64,6 @@ describe("TokenCache tests", () => { cacheConfig = { temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; logger = new Logger({ diff --git a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts index 70af23cb34..82574a3c3b 100644 --- a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts +++ b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts @@ -91,7 +91,6 @@ import { BrowserPerformanceClient } from "../../src/telemetry/BrowserPerformance const cacheConfig = { cacheLocation: BrowserCacheLocation.SessionStorage, temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - cacheMigrationEnabled: false, claimsBasedCachingEnabled: false, }; From 91f9f57404aeff317780436bacbc7fad374051c4 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Sat, 12 Apr 2025 12:50:15 -0700 Subject: [PATCH 05/24] Deprecate claimsBasedCachingEnabled --- lib/msal-browser/docs/configuration.md | 4 ++-- lib/msal-browser/src/config/Configuration.ts | 2 ++ lib/msal-common/src/config/ClientConfiguration.ts | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/msal-browser/docs/configuration.md b/lib/msal-browser/docs/configuration.md index 10583cbc09..f14ee98830 100644 --- a/lib/msal-browser/docs/configuration.md +++ b/lib/msal-browser/docs/configuration.md @@ -95,8 +95,8 @@ const msalInstance = new PublicClientApplication(msalConfig); | Option | Description | Format | Default Value | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | | `cacheLocation` | Location of token cache in browser. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | -| `temporaryCacheLocation` | Location of temporary cache in browser. This option should only be changed for specific edge cases. Please refer to [caching](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/caching.md#cached-artifacts) for more. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | -| `claimsBasedCachingEnabled` | If `true`, access tokens will be cached under a key containing the hash of the requested claims string, resulting in a cache miss and new network token request when the same token request is made with different or missing claims. If set to `false`, tokens will be cached without claims, but all requests containing claims will go to the network and overwrite any previously cached token with the same scopes. | boolean | `false` | +| `temporaryCacheLocation` | Location of temporary cache in browser. This option should only be changed for specific edge cases. Please refer to [caching](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/caching.md#cached-artifacts) for more. **Note: This is deprecated and will be removed in a future release.** | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | +| `claimsBasedCachingEnabled` | If `true`, access tokens will be cached under a key containing the hash of the requested claims string, resulting in a cache miss and new network token request when the same token request is made with different or missing claims. If set to `false`, tokens will be cached without claims, but all requests containing claims will go to the network and overwrite any previously cached token with the same scopes. **Note: This is deprecated and will be removed in a future release.** | boolean | `false` | See [Caching in MSAL](./caching.md) for more. diff --git a/lib/msal-browser/src/config/Configuration.ts b/lib/msal-browser/src/config/Configuration.ts index ae49e43d59..dac280dcf4 100644 --- a/lib/msal-browser/src/config/Configuration.ts +++ b/lib/msal-browser/src/config/Configuration.ts @@ -128,6 +128,8 @@ export type CacheOptions = { */ temporaryCacheLocation?: BrowserCacheLocation | string; /** + * @deprecated + * claimsBasedCachingEnabled is deprecated and will be removed in a future release. * Flag that determines whether access tokens are stored based on requested claims */ claimsBasedCachingEnabled?: boolean; diff --git a/lib/msal-common/src/config/ClientConfiguration.ts b/lib/msal-common/src/config/ClientConfiguration.ts index e3eecd1206..efa8fc13a2 100644 --- a/lib/msal-common/src/config/ClientConfiguration.ts +++ b/lib/msal-common/src/config/ClientConfiguration.ts @@ -126,6 +126,10 @@ export type LoggerOptions = { * - claimsBasedCachingEnabled - Sets whether tokens should be cached based on the claims hash. Default is false. */ export type CacheOptions = { + /** + * @deprecated + * claimsBasedCachingEnabled is deprecated and will be removed in a future release. + */ claimsBasedCachingEnabled?: boolean; }; From b5814146668d13df3f76896abb8d6659494e6c27 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Sat, 12 Apr 2025 12:52:41 -0700 Subject: [PATCH 06/24] Format:fix --- lib/msal-browser/src/utils/BrowserUtils.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/msal-browser/src/utils/BrowserUtils.ts b/lib/msal-browser/src/utils/BrowserUtils.ts index 02825ae3e7..bb89637f98 100644 --- a/lib/msal-browser/src/utils/BrowserUtils.ts +++ b/lib/msal-browser/src/utils/BrowserUtils.ts @@ -172,9 +172,7 @@ export function redirectPreflightCheck( preflightCheck(initialized); blockRedirectInIframe(config.system.allowRedirectInIframe); // Block redirects if memory storage is enabled - if ( - config.cache.cacheLocation === BrowserCacheLocation.MemoryStorage - ) { + if (config.cache.cacheLocation === BrowserCacheLocation.MemoryStorage) { throw createBrowserConfigurationAuthError( BrowserConfigurationAuthErrorCodes.inMemRedirectUnavailable ); From a0187a413bfc06720d8cbfb989e35b411e131413 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Sat, 12 Apr 2025 12:54:37 -0700 Subject: [PATCH 07/24] Change files --- ...-msal-browser-6f00d163-ea6e-4461-8d64-f654afaa2e5c.json | 7 +++++++ ...e-msal-common-c037e1e0-4f7a-49c5-912a-ce0ea99fcf1e.json | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 change/@azure-msal-browser-6f00d163-ea6e-4461-8d64-f654afaa2e5c.json create mode 100644 change/@azure-msal-common-c037e1e0-4f7a-49c5-912a-ce0ea99fcf1e.json diff --git a/change/@azure-msal-browser-6f00d163-ea6e-4461-8d64-f654afaa2e5c.json b/change/@azure-msal-browser-6f00d163-ea6e-4461-8d64-f654afaa2e5c.json new file mode 100644 index 0000000000..b0d6506a2c --- /dev/null +++ b/change/@azure-msal-browser-6f00d163-ea6e-4461-8d64-f654afaa2e5c.json @@ -0,0 +1,7 @@ +{ + "type": "major", + "comment": "Configuration changes to CacheOptions #7697", + "packageName": "@azure/msal-browser", + "email": "joarroyo@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@azure-msal-common-c037e1e0-4f7a-49c5-912a-ce0ea99fcf1e.json b/change/@azure-msal-common-c037e1e0-4f7a-49c5-912a-ce0ea99fcf1e.json new file mode 100644 index 0000000000..9a6b28c4e0 --- /dev/null +++ b/change/@azure-msal-common-c037e1e0-4f7a-49c5-912a-ce0ea99fcf1e.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Deprecate claimsBasedCachingEnabled as part of Configuration change #7697", + "packageName": "@azure/msal-common", + "email": "joarroyo@microsoft.com", + "dependentChangeType": "patch" +} From bac042da920ff4775bac64006f033ba2434c8d49 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Tue, 15 Apr 2025 12:10:16 -0700 Subject: [PATCH 08/24] apiExtractor --- lib/msal-browser/apiReview/msal-browser.api.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/msal-browser/apiReview/msal-browser.api.md b/lib/msal-browser/apiReview/msal-browser.api.md index 5ddce4d665..8667c7cdde 100644 --- a/lib/msal-browser/apiReview/msal-browser.api.md +++ b/lib/msal-browser/apiReview/msal-browser.api.md @@ -411,8 +411,6 @@ export type CacheLookupPolicy = (typeof CacheLookupPolicy)[keyof typeof CacheLoo export type CacheOptions = { cacheLocation?: BrowserCacheLocation | string; temporaryCacheLocation?: BrowserCacheLocation | string; - storeAuthStateInCookie?: boolean; - cacheMigrationEnabled?: boolean; claimsBasedCachingEnabled?: boolean; }; @@ -1493,7 +1491,7 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU]; // src/cache/LocalStorage.ts:296:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:354:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:385:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/config/Configuration.ts:236:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts +// src/config/Configuration.ts:232:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts // src/event/EventHandler.ts:113:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/event/EventHandler.ts:139:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" From e0f8803fd9416d433ff98449ec87298706e67bdf Mon Sep 17 00:00:00 2001 From: joarroyo Date: Wed, 16 Apr 2025 10:44:59 -0700 Subject: [PATCH 09/24] Update apiExtractor after merge --- lib/msal-browser/apiReview/msal-browser.api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msal-browser/apiReview/msal-browser.api.md b/lib/msal-browser/apiReview/msal-browser.api.md index 3e868e3c62..707249161d 100644 --- a/lib/msal-browser/apiReview/msal-browser.api.md +++ b/lib/msal-browser/apiReview/msal-browser.api.md @@ -1490,7 +1490,7 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU]; // src/cache/LocalStorage.ts:296:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:354:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:385:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/config/Configuration.ts:231:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts +// src/config/Configuration.ts:227:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts // src/event/EventHandler.ts:113:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/event/EventHandler.ts:139:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" From cd106bc4631b60bf1995513e68eaae6ff5723502 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Wed, 16 Apr 2025 14:55:18 -0700 Subject: [PATCH 10/24] Update apiExtractor after merge --- lib/msal-browser/apiReview/msal-browser.api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msal-browser/apiReview/msal-browser.api.md b/lib/msal-browser/apiReview/msal-browser.api.md index 6095ccac18..ec7148510b 100644 --- a/lib/msal-browser/apiReview/msal-browser.api.md +++ b/lib/msal-browser/apiReview/msal-browser.api.md @@ -1489,7 +1489,7 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU]; // src/cache/LocalStorage.ts:296:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:354:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:385:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/config/Configuration.ts:227:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts +// src/config/Configuration.ts:223:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts // src/event/EventHandler.ts:113:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/event/EventHandler.ts:139:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" From 4539d7dc87bc5d3095bda895c11bcab768ab427a Mon Sep 17 00:00:00 2001 From: joarroyo Date: Wed, 23 Apr 2025 12:20:57 -0700 Subject: [PATCH 11/24] Remove temporaryCacheLocation and claimsBasedCachingEnabled options and references --- lib/msal-browser/docs/caching.md | 12 +- lib/msal-browser/docs/configuration.md | 12 - lib/msal-browser/docs/errors.md | 3 +- .../src/cache/BrowserCacheManager.ts | 4 +- lib/msal-browser/src/config/Configuration.ts | 16 - .../src/controllers/StandardController.ts | 26 +- .../StandardInteractionClient.ts | 4 - .../src/request/RequestHelpers.ts | 3 +- .../test/app/PublicClientApplication.spec.ts | 389 -------- .../test/cache/BrowserCacheManager.spec.ts | 921 ------------------ .../test/cache/TokenCache.spec.ts | 2 - .../test/config/Configuration.spec.ts | 3 - .../interaction_client/RedirectClient.spec.ts | 2 - .../test/request/RequestHelpers.spec.ts | 139 +++ .../src/client/SilentFlowClient.ts | 4 +- .../src/config/ClientConfiguration.ts | 15 +- .../test/client/SilentFlowClient.spec.ts | 66 -- .../test/config/ClientConfiguration.spec.ts | 9 +- .../app/customizable-e2e-test/testConfig.json | 20 +- 19 files changed, 177 insertions(+), 1473 deletions(-) create mode 100644 lib/msal-browser/test/request/RequestHelpers.spec.ts diff --git a/lib/msal-browser/docs/caching.md b/lib/msal-browser/docs/caching.md index 34ae27b430..10b6b41466 100644 --- a/lib/msal-browser/docs/caching.md +++ b/lib/msal-browser/docs/caching.md @@ -66,20 +66,10 @@ To faciliate efficient token acquisition while maintaining a good UX, MSAL cache - previous failed request - performance data -> :bulb: Temporary cache entries will always be stored in session storage or in memory unless overridden by the user with the `temporaryCacheLocation` cache option. MSAL will fallback to memory storage if local/session storage is not available. Please read the warning below for more information. +> :bulb: Temporary cache entries will always be stored in session storage or in memory. MSAL will fallback to memory storage if local/session storage is not available. Please read the warning below for more information. > :bulb: The authorization code is only stored in memory and will be discarded after redeeming it for tokens. -## Warning :warning: - -**NOTE: `temporaryCacheLocation` is deprecated will be removed in the next major version.** - -Overriding `temporaryCacheLocation` should be done with caution. Specifically when choosing `localStorage`. Interaction in more than one tab/window will not be supported and you may receive `interaction_in_progress` errors unexpectedly. This is an escape hatch, not a fully supported feature. - -When using MSAL.js with the default configuration in a scenario where the user is redirected after successful authentication in a new window or tab, the OAuth 2.0 Authorization Code with PKCE flow will be interrupted. In this case, the original window or tab where the authentication state (code verifier and challenge) are stored, will be lost, and the authentication flow will fail. - -To handle this scenario, you can configure MSAL to use `localStorage` as the cache location by overriding the `temporaryCacheLocation` configuration property. This allows the code verifier and challenge to be stored in the browser's `localStorage,` which is persistent across multiple tabs and windows. - ## Remarks - We do not recommend apps having business logic dependent on direct use of entities in the cache. Instead, use the appropriate MSAL API when you need to acquire tokens or retrieve accounts. diff --git a/lib/msal-browser/docs/configuration.md b/lib/msal-browser/docs/configuration.md index 8c6e903b52..c65257e8a7 100644 --- a/lib/msal-browser/docs/configuration.md +++ b/lib/msal-browser/docs/configuration.md @@ -22,8 +22,6 @@ const msalConfig = { }, cache: { cacheLocation: "sessionStorage", - temporaryCacheLocation: "sessionStorage", - claimsBasedCachingEnabled: true, }, system: { loggerOptions: { @@ -94,16 +92,6 @@ const msalInstance = new PublicClientApplication(msalConfig); | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | | `cacheLocation` | Location of token cache in browser. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | -**Note: The following cache config options are deprecated and will be removed in the next major version** - -| Option | Description | Format | Default Value | -| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | -| `temporaryCacheLocation` | Location of temporary cache in browser. This option should only be changed for specific edge cases. Please refer to [caching](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/caching.md#cached-artifacts) for more. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` | -| `storeAuthStateInCookie` | If true, stores cache items in cookies as well as browser cache. Should be set to true for use cases using IE. | boolean | `false` | -| `secureCookies` | If true and `storeAuthStateInCookies` is also enabled, MSAL adds the `Secure` flag to the browser cookie so it can only be sent over HTTPS. | boolean | `false` | -| `cacheMigrationEnabled` | If true, cache entries from older versions of MSAL will be updated to conform to the latest cache schema on startup. If your application has not been recently updated to a new version of MSAL.js you can safely turn this off. In the event old cache entries are not migrated it may result in a cache miss when attempting to retrieve accounts or tokens and affected users may need to re-authenticate to get up to date. | boolean | `true` when using `localStorage`, `false` otherwise | -| `claimsBasedCachingEnabled` | If `true`, access tokens will be cached under a key containing the hash of the requested claims string, resulting in a cache miss and new network token request when the same token request is made with different or missing claims. If set to `false`, tokens will be cached without claims, but all requests containing claims will go to the network and overwrite any previously cached token with the same scopes. | boolean | `false` | - See [Caching in MSAL](./caching.md) for more. ### System Config Options diff --git a/lib/msal-browser/docs/errors.md b/lib/msal-browser/docs/errors.md index 70d7305439..7d8c5f10fb 100644 --- a/lib/msal-browser/docs/errors.md +++ b/lib/msal-browser/docs/errors.md @@ -437,5 +437,4 @@ This error occurs when MSAL.js surpasses the allotted storage limit when attempt **Mitigation**: -1. Make sure the configured cache storage has enough capacity to allow MSAL.js to persist token payload. The amount of cache storage required depends on the number of [cached artifacts](./caching.md#cached-artifacts). -2. Disable [claimsBasedCachingEnabled](./configuration.md#cache-config-options) cache config option. When enabled, it caches access tokens under a key containing the hash of the requested claims. Depending on the MSAL.js API usage, it may result in the vast number of access tokens persisted in the cache storage. +Make sure the configured cache storage has enough capacity to allow MSAL.js to persist token payload. The amount of cache storage required depends on the number of [cached artifacts](./caching.md#cached-artifacts). diff --git a/lib/msal-browser/src/cache/BrowserCacheManager.ts b/lib/msal-browser/src/cache/BrowserCacheManager.ts index 0c6621738a..5a447f0e80 100644 --- a/lib/msal-browser/src/cache/BrowserCacheManager.ts +++ b/lib/msal-browser/src/cache/BrowserCacheManager.ts @@ -109,7 +109,7 @@ export class BrowserCacheManager extends CacheManager { ); this.temporaryCacheStorage = getStorageImplementation( clientId, - cacheConfig.temporaryCacheLocation, + BrowserCacheLocation.SessionStorage, logger, performanceClient ); @@ -1344,8 +1344,6 @@ export const DEFAULT_BROWSER_CACHE_MANAGER = ( ): BrowserCacheManager => { const cacheOptions: Required = { cacheLocation: BrowserCacheLocation.MemoryStorage, - temporaryCacheLocation: BrowserCacheLocation.MemoryStorage, - claimsBasedCachingEnabled: false, }; return new BrowserCacheManager( clientId, diff --git a/lib/msal-browser/src/config/Configuration.ts b/lib/msal-browser/src/config/Configuration.ts index 2b7625ec0c..876b0043b2 100644 --- a/lib/msal-browser/src/config/Configuration.ts +++ b/lib/msal-browser/src/config/Configuration.ts @@ -113,20 +113,6 @@ export type CacheOptions = { * Used to specify the cacheLocation user wants to set. Valid values are "localStorage", "sessionStorage" and "memoryStorage". */ cacheLocation?: BrowserCacheLocation | string; - /** - * @deprecated - * temporaryCacheLocation is deprecated and will be removed in a future release. - * Used to specify the temporaryCacheLocation user wants to set. Valid values are "localStorage", "sessionStorage" and "memoryStorage". - * @deprecated This option is deprecated and will be removed in the next major version. - */ - temporaryCacheLocation?: BrowserCacheLocation | string; - /** - * @deprecated - * claimsBasedCachingEnabled is deprecated and will be removed in a future release. - * Flag that determines whether access tokens are stored based on requested claims - * @deprecated This option is deprecated and will be removed in the next major version. - */ - claimsBasedCachingEnabled?: boolean; }; export type BrowserSystemOptions = SystemOptions & { @@ -276,8 +262,6 @@ export function buildConfiguration( // Default cache options for browser const DEFAULT_CACHE_OPTIONS: Required = { cacheLocation: BrowserCacheLocation.SessionStorage, - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - claimsBasedCachingEnabled: false, }; // Default logger options for browser diff --git a/lib/msal-browser/src/controllers/StandardController.ts b/lib/msal-browser/src/controllers/StandardController.ts index 0938508c5d..6cec3528ff 100644 --- a/lib/msal-browser/src/controllers/StandardController.ts +++ b/lib/msal-browser/src/controllers/StandardController.ts @@ -256,8 +256,6 @@ export class StandardController implements IController { // initialize in memory storage for native flows const nativeCacheOptions: Required = { cacheLocation: BrowserCacheLocation.MemoryStorage, - temporaryCacheLocation: BrowserCacheLocation.MemoryStorage, - claimsBasedCachingEnabled: false, }; this.nativeInternalStorage = new BrowserCacheManager( this.config.auth.clientId, @@ -356,21 +354,15 @@ export class StandardController implements IController { } } - if (!this.config.cache.claimsBasedCachingEnabled) { - this.logger.verbose( - "Claims-based caching is disabled. Clearing the previous cache with claims" - ); - - await invokeAsync( - this.browserStorage.clearTokensAndKeysWithClaims.bind( - this.browserStorage - ), - PerformanceEvents.ClearTokensAndKeysWithClaims, - this.logger, - this.performanceClient, - initCorrelationId - )(this.performanceClient, initCorrelationId); - } + await invokeAsync( + this.browserStorage.clearTokensAndKeysWithClaims.bind( + this.browserStorage + ), + PerformanceEvents.ClearTokensAndKeysWithClaims, + this.logger, + this.performanceClient, + initCorrelationId + )(this.performanceClient, initCorrelationId); if ( this.config.cache.cacheLocation === diff --git a/lib/msal-browser/src/interaction_client/StandardInteractionClient.ts b/lib/msal-browser/src/interaction_client/StandardInteractionClient.ts index 995d0adeee..22a2065074 100644 --- a/lib/msal-browser/src/interaction_client/StandardInteractionClient.ts +++ b/lib/msal-browser/src/interaction_client/StandardInteractionClient.ts @@ -263,10 +263,6 @@ export abstract class StandardInteractionClient extends BaseInteractionClient { logLevel: logger.logLevel, correlationId: this.correlationId, }, - cacheOptions: { - claimsBasedCachingEnabled: - this.config.cache.claimsBasedCachingEnabled, - }, cryptoInterface: this.browserCrypto, networkInterface: this.networkClient, storageInterface: this.browserStorage, diff --git a/lib/msal-browser/src/request/RequestHelpers.ts b/lib/msal-browser/src/request/RequestHelpers.ts index b37697f28b..36884dda11 100644 --- a/lib/msal-browser/src/request/RequestHelpers.ts +++ b/lib/msal-browser/src/request/RequestHelpers.ts @@ -71,9 +71,8 @@ export async function initializeBaseRequest( ); } - // Set requested claims hash if claims-based caching is enabled and claims were requested + // Set requested claims hash if claims were requested if ( - config.cache.claimsBasedCachingEnabled && request.claims && // Checks for empty stringified object "{}" which doesn't qualify as requested claims !StringUtils.isEmptyObj(request.claims) diff --git a/lib/msal-browser/test/app/PublicClientApplication.spec.ts b/lib/msal-browser/test/app/PublicClientApplication.spec.ts index 3c2d0772d9..49745b4261 100644 --- a/lib/msal-browser/test/app/PublicClientApplication.spec.ts +++ b/lib/msal-browser/test/app/PublicClientApplication.spec.ts @@ -118,9 +118,7 @@ import { import { INTERACTION_TYPE } from "../../src/utils/BrowserConstants.js"; const cacheConfig = { - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - claimsBasedCachingEnabled: false, }; let testAppConfig = { @@ -4660,127 +4658,6 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { expect(parallelResponse).toHaveLength(3); }); - it("makes one network request with multiple parallel silent requests with same request including claims when claimsBasedCaching is enabled", async () => { - pca = new PublicClientApplication({ - auth: { - clientId: TEST_CONFIG.MSAL_CLIENT_ID, - }, - system: { - allowPlatformBroker: false, - }, - cache: { - claimsBasedCachingEnabled: true, - }, - }); - - await pca.initialize(); - const testServerTokenResponse = { - token_type: TEST_CONFIG.TOKEN_TYPE_BEARER, - scope: TEST_CONFIG.DEFAULT_SCOPES.join(" "), - expires_in: TEST_TOKEN_LIFETIMES.DEFAULT_EXPIRES_IN, - ext_expires_in: TEST_TOKEN_LIFETIMES.DEFAULT_EXPIRES_IN, - access_token: TEST_TOKENS.ACCESS_TOKEN, - refresh_token: TEST_TOKENS.REFRESH_TOKEN, - id_token: TEST_TOKENS.IDTOKEN_V2, - }; - const testIdTokenClaims: TokenClaims = { - ver: "2.0", - iss: "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0", - sub: "AAAAAAAAAAAAAAAAAAAAAIkzqFVrSaSaFHy782bbtaQ", - name: "Abe Lincoln", - preferred_username: "AbeLi@microsoft.com", - oid: "00000000-0000-0000-66f3-3332eca7ea81", - tid: "3338040d-6c67-4c5b-b112-36a304b66dad", - nonce: "123523", - }; - const testAccount: AccountInfo = { - homeAccountId: TEST_DATA_CLIENT_INFO.TEST_HOME_ACCOUNT_ID, - localAccountId: TEST_DATA_CLIENT_INFO.TEST_UID, - environment: "login.windows.net", - tenantId: testIdTokenClaims.tid || "", - username: testIdTokenClaims.preferred_username || "", - }; - const testTokenResponse: AuthenticationResult = { - authority: TEST_CONFIG.validAuthority, - uniqueId: testIdTokenClaims.oid || "", - tenantId: testIdTokenClaims.tid || "", - scopes: [...TEST_CONFIG.DEFAULT_SCOPES, "User.Read"], - idToken: testServerTokenResponse.id_token, - idTokenClaims: testIdTokenClaims, - accessToken: testServerTokenResponse.access_token, - fromCache: false, - correlationId: RANDOM_TEST_GUID, - expiresOn: TestTimeUtils.nowDateWithOffset( - testServerTokenResponse.expires_in - ), - account: testAccount, - tokenType: AuthenticationScheme.BEARER, - }; - jest.spyOn(BrowserCrypto, "createNewGuid").mockReturnValue( - RANDOM_TEST_GUID - ); - jest.spyOn(CryptoOps.prototype, "hashString").mockResolvedValue( - TEST_CRYPTO_VALUES.TEST_SHA256_HASH - ); - const atsSpy: jest.SpyInstance = jest.spyOn( - StandardController.prototype, - "acquireTokenSilentAsync" - ); - const silentATStub: jest.SpyInstance = jest - .spyOn( - RefreshTokenClient.prototype, - "acquireTokenByRefreshToken" - ) - .mockResolvedValue(testTokenResponse); - const tokenRequest: CommonSilentFlowRequest = { - scopes: ["User.Read"], - account: testAccount, - authority: TEST_CONFIG.validAuthority, - authenticationScheme: AuthenticationScheme.BEARER, - claims: JSON.stringify({ claim: "claim" }), - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - }; - const expectedTokenRequest: CommonSilentFlowRequest = { - ...tokenRequest, - scopes: ["User.Read"], - authority: `${Constants.DEFAULT_AUTHORITY}`, - correlationId: RANDOM_TEST_GUID, - claims: JSON.stringify({ claim: "claim" }), - requestedClaimsHash: TEST_CRYPTO_VALUES.TEST_SHA256_HASH, - forceRefresh: false, - }; - - const silentRequest1 = pca.acquireTokenSilent(tokenRequest); - const silentRequest2 = pca.acquireTokenSilent({ - ...tokenRequest, - correlationId: "test-correlationId2", - }); - const silentRequest3 = pca.acquireTokenSilent({ - ...tokenRequest, - correlationId: "test-correlationId3", - }); - const parallelResponse = await Promise.all([ - silentRequest1, - silentRequest2, - silentRequest3, - ]); - - expect(silentATStub).toHaveBeenCalledWith(expectedTokenRequest); - expect(atsSpy).toHaveBeenCalledTimes(1); - expect(silentATStub).toHaveBeenCalledTimes(1); - expect(parallelResponse[0]).toEqual(testTokenResponse); - expect(parallelResponse[1]).toEqual({ - ...testTokenResponse, - correlationId: "test-correlationId2", - }); - expect(parallelResponse[2]).toEqual({ - ...testTokenResponse, - correlationId: "test-correlationId3", - }); - expect(parallelResponse).toHaveLength(3); - }); - it("makes network requests for each distinct request when acquireTokenSilent is called in parallel", async () => { const testServerTokenResponse = { token_type: TEST_CONFIG.TOKEN_TYPE_BEARER, @@ -4982,270 +4859,6 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { expect(silentATStub).toHaveBeenCalledTimes(6); }); - it("makes network requests for each distinct request including claims when acquireTokenSilent is called in parallel with claimsBasedCaching is enabled", async () => { - pca = new PublicClientApplication({ - auth: { - clientId: TEST_CONFIG.MSAL_CLIENT_ID, - }, - system: { - allowPlatformBroker: false, - }, - cache: { - claimsBasedCachingEnabled: true, - }, - }); - - await pca.initialize(); - const testServerTokenResponse = { - token_type: TEST_CONFIG.TOKEN_TYPE_BEARER, - scope: TEST_CONFIG.DEFAULT_SCOPES.join(" "), - expires_in: TEST_TOKEN_LIFETIMES.DEFAULT_EXPIRES_IN, - ext_expires_in: TEST_TOKEN_LIFETIMES.DEFAULT_EXPIRES_IN, - access_token: TEST_TOKENS.ACCESS_TOKEN, - refresh_token: TEST_TOKENS.REFRESH_TOKEN, - id_token: TEST_TOKENS.IDTOKEN_V2, - }; - const testIdTokenClaims: TokenClaims = { - ver: "2.0", - iss: "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0", - sub: "AAAAAAAAAAAAAAAAAAAAAIkzqFVrSaSaFHy782bbtaQ", - name: "Abe Lincoln", - preferred_username: "AbeLi@microsoft.com", - oid: "00000000-0000-0000-66f3-3332eca7ea81", - tid: "3338040d-6c67-4c5b-b112-36a304b66dad", - nonce: "123523", - }; - const testAccount: AccountInfo = { - homeAccountId: TEST_DATA_CLIENT_INFO.TEST_HOME_ACCOUNT_ID, - localAccountId: TEST_DATA_CLIENT_INFO.TEST_UID, - environment: "login.windows.net", - tenantId: testIdTokenClaims.tid || "", - username: testIdTokenClaims.preferred_username || "", - }; - const testTokenResponse: AuthenticationResult = { - authority: TEST_CONFIG.validAuthority, - uniqueId: testIdTokenClaims.oid || "", - tenantId: testIdTokenClaims.tid || "", - scopes: [...TEST_CONFIG.DEFAULT_SCOPES, "User.Read"], - idToken: testServerTokenResponse.id_token, - idTokenClaims: testIdTokenClaims, - accessToken: testServerTokenResponse.access_token, - fromCache: false, - correlationId: RANDOM_TEST_GUID, - expiresOn: TestTimeUtils.nowDateWithOffset( - testServerTokenResponse.expires_in - ), - account: testAccount, - tokenType: AuthenticationScheme.BEARER, - }; - jest.spyOn(BrowserCrypto, "createNewGuid").mockReturnValue( - RANDOM_TEST_GUID - ); - jest.spyOn(BrowserCrypto, "hashString").mockResolvedValue( - TEST_CRYPTO_VALUES.TEST_SHA256_HASH - ); - const silentATStub: jest.SpyInstance = jest - .spyOn( - RefreshTokenClient.prototype, - "acquireTokenByRefreshToken" - ) - .mockResolvedValue(testTokenResponse); - // Beaerer requests - const tokenRequest1: CommonSilentFlowRequest = { - scopes: ["User.Read"], - account: testAccount, - authority: TEST_CONFIG.validAuthority, - authenticationScheme: AuthenticationScheme.BEARER, - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - }; - const expectedTokenRequest1: CommonSilentFlowRequest = { - ...tokenRequest1, - scopes: ["User.Read"], - authority: `${Constants.DEFAULT_AUTHORITY}`, - correlationId: RANDOM_TEST_GUID, - forceRefresh: false, - }; - const tokenRequest2: CommonSilentFlowRequest = { - scopes: ["Mail.Read"], - account: testAccount, - authority: TEST_CONFIG.validAuthority, - authenticationScheme: AuthenticationScheme.BEARER, - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - }; - const expectedTokenRequest2: CommonSilentFlowRequest = { - ...tokenRequest1, - scopes: ["Mail.Read"], - authority: `${Constants.DEFAULT_AUTHORITY}`, - correlationId: RANDOM_TEST_GUID, - forceRefresh: false, - }; - - // PoP requests - const popTokenRequest1: CommonSilentFlowRequest = { - scopes: ["User.Read"], - account: testAccount, - authority: TEST_CONFIG.validAuthority, - authenticationScheme: AuthenticationScheme.POP, - resourceRequestMethod: "GET", - resourceRequestUri: "https://testUri.com/user.read", - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - }; - - const popTokenRequest2: CommonSilentFlowRequest = { - scopes: ["Mail.Read"], - account: testAccount, - authority: TEST_CONFIG.validAuthority, - authenticationScheme: AuthenticationScheme.POP, - resourceRequestMethod: "GET", - resourceRequestUri: "https://testUri.com/mail.read", - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - }; - const expectedPopTokenRequest1: CommonSilentFlowRequest = { - ...popTokenRequest1, - scopes: ["User.Read"], - authority: `${Constants.DEFAULT_AUTHORITY}`, - correlationId: RANDOM_TEST_GUID, - forceRefresh: false, - }; - - const expectedPopTokenRequest2: CommonSilentFlowRequest = { - ...popTokenRequest2, - scopes: ["Mail.Read"], - authority: `${Constants.DEFAULT_AUTHORITY}`, - correlationId: RANDOM_TEST_GUID, - forceRefresh: false, - }; - - // SSH Certificate requests - const sshCertRequest1: CommonSilentFlowRequest = { - scopes: ["User.Read"], - account: testAccount, - authority: TEST_CONFIG.validAuthority, - authenticationScheme: AuthenticationScheme.SSH, - sshJwk: TEST_SSH_VALUES.ENCODED_SSH_JWK, - sshKid: TEST_SSH_VALUES.SSH_KID, - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - }; - - const sshCertRequest2: CommonSilentFlowRequest = { - scopes: ["Mail.Read"], - account: testAccount, - authority: TEST_CONFIG.validAuthority, - authenticationScheme: AuthenticationScheme.SSH, - sshJwk: TEST_SSH_VALUES.ALTERNATE_ENCODED_SSH_JWK, - sshKid: TEST_SSH_VALUES.ALTERNATE_SSH_KID, - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - }; - - const expectedSshCertificateRequest1: CommonSilentFlowRequest = { - ...sshCertRequest1, - scopes: ["User.Read"], - authority: `${Constants.DEFAULT_AUTHORITY}`, - correlationId: RANDOM_TEST_GUID, - forceRefresh: false, - }; - - const expectedSshCertificateRequest2: CommonSilentFlowRequest = { - ...sshCertRequest2, - scopes: ["Mail.Read"], - authority: `${Constants.DEFAULT_AUTHORITY}`, - correlationId: RANDOM_TEST_GUID, - forceRefresh: false, - }; - - // Requests with claims - const claimsRequest1: CommonSilentFlowRequest = { - scopes: ["User.Read"], - account: testAccount, - authority: TEST_CONFIG.validAuthority, - authenticationScheme: AuthenticationScheme.BEARER, - claims: JSON.stringify({ claim1: "claim1" }), - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - }; - - const claimsRequest2: CommonSilentFlowRequest = { - scopes: ["User.Read"], - account: testAccount, - authority: TEST_CONFIG.validAuthority, - authenticationScheme: AuthenticationScheme.BEARER, - claims: JSON.stringify({ claim2: "claim2" }), - requestedClaimsHash: TEST_CRYPTO_VALUES.TEST_SHA256_HASH, - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - }; - - const expectedClaimsRequest1: CommonSilentFlowRequest = { - ...claimsRequest1, - scopes: ["User.Read"], - authority: `${Constants.DEFAULT_AUTHORITY}`, - correlationId: RANDOM_TEST_GUID, - claims: JSON.stringify({ claim1: "claim1" }), - requestedClaimsHash: TEST_CRYPTO_VALUES.TEST_SHA256_HASH, - forceRefresh: false, - }; - - const expectedClaimsRequest2: CommonSilentFlowRequest = { - ...claimsRequest2, - scopes: ["User.Read"], - authority: `${Constants.DEFAULT_AUTHORITY}`, - correlationId: RANDOM_TEST_GUID, - claims: JSON.stringify({ claim2: "claim2" }), - requestedClaimsHash: TEST_CRYPTO_VALUES.TEST_SHA256_HASH, - forceRefresh: false, - }; - - const silentRequest1 = pca.acquireTokenSilent(tokenRequest1); - const silentRequest2 = pca.acquireTokenSilent(tokenRequest1); - const silentRequest3 = pca.acquireTokenSilent(tokenRequest2); - const popSilentRequest1 = pca.acquireTokenSilent(popTokenRequest1); - const popSilentRequest2 = pca.acquireTokenSilent(popTokenRequest1); - const popSilentRequest3 = pca.acquireTokenSilent(popTokenRequest2); - const sshCertSilentRequest1 = - pca.acquireTokenSilent(sshCertRequest1); - const sshCertSilentRequest2 = - pca.acquireTokenSilent(sshCertRequest1); - const sshCertSilentRequest3 = - pca.acquireTokenSilent(sshCertRequest2); - const claimsSilentRequest1 = pca.acquireTokenSilent(claimsRequest1); - const claimsSilentRequest2 = pca.acquireTokenSilent(claimsRequest1); - const claimsSilentRequest3 = pca.acquireTokenSilent(claimsRequest2); - await Promise.all([ - silentRequest1, - silentRequest2, - silentRequest3, - popSilentRequest1, - popSilentRequest2, - popSilentRequest3, - sshCertSilentRequest1, - sshCertSilentRequest2, - sshCertSilentRequest3, - claimsSilentRequest1, - claimsSilentRequest2, - claimsSilentRequest3, - ]); - - expect(silentATStub).toHaveBeenCalledWith(expectedTokenRequest1); - expect(silentATStub).toHaveBeenCalledWith(expectedTokenRequest2); - expect(silentATStub).toHaveBeenCalledWith(expectedPopTokenRequest1); - expect(silentATStub).toHaveBeenCalledWith(expectedPopTokenRequest2); - expect(silentATStub).toHaveBeenCalledWith( - expectedSshCertificateRequest1 - ); - expect(silentATStub).toHaveBeenCalledWith( - expectedSshCertificateRequest2 - ); - expect(silentATStub).toHaveBeenCalledWith(expectedClaimsRequest1); - expect(silentATStub).toHaveBeenCalledWith(expectedClaimsRequest2); - expect(silentATStub).toHaveBeenCalledTimes(8); - }); - it("makes network requests for identical requests for different embedded apps when acquireTokenSilent is called in parallel", async () => { const testServerTokenResponse = { token_type: TEST_CONFIG.TOKEN_TYPE_BEARER, @@ -7286,8 +6899,6 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { TEST_CONFIG.MSAL_CLIENT_ID, { cacheLocation: BrowserCacheLocation.LocalStorage, - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - claimsBasedCachingEnabled: false, }, new CryptoOps(new Logger({})), new Logger({}), diff --git a/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts b/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts index 52fbdcb435..c90c1802a0 100644 --- a/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts +++ b/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts @@ -59,9 +59,7 @@ describe("BrowserCacheManager tests", () => { let browserCrypto: CryptoOps; beforeEach(() => { cacheConfig = { - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - claimsBasedCachingEnabled: false, }; logger = new Logger({ loggerCallback: ( @@ -1477,925 +1475,6 @@ describe("BrowserCacheManager tests", () => { }); }); - describe("Interface functions with overridden temporaryCacheLocation", () => { - let browserSessionStorage: BrowserCacheManager; - let authority: Authority; - let browserLocalStorage: BrowserCacheManager; - let cacheVal: string; - let msalCacheKey: string; - let msalCacheKey2: string; - beforeEach(async () => { - browserSessionStorage = new BrowserCacheManager( - TEST_CONFIG.MSAL_CLIENT_ID, - cacheConfig, - browserCrypto, - logger, - new StubPerformanceClient(), - new EventHandler() - ); - authority = new Authority( - TEST_CONFIG.validAuthority, - StubbedNetworkModule, - browserSessionStorage, - { - protocolMode: ProtocolMode.AAD, - authorityMetadata: "", - cloudDiscoveryMetadata: "", - knownAuthorities: [], - }, - logger, - TEST_CONFIG.CORRELATION_ID - ); - jest.spyOn( - Authority.prototype, - "getPreferredCache" - ).mockReturnValue("login.microsoftonline.com"); - browserLocalStorage = new BrowserCacheManager( - TEST_CONFIG.MSAL_CLIENT_ID, - { - ...cacheConfig, - cacheLocation: BrowserCacheLocation.LocalStorage, - temporaryCacheLocation: BrowserCacheLocation.LocalStorage, - }, - browserCrypto, - logger, - new StubPerformanceClient(), - new EventHandler() - ); - await browserLocalStorage.initialize(TEST_CONFIG.CORRELATION_ID); - await browserSessionStorage.initialize(TEST_CONFIG.CORRELATION_ID); - cacheVal = "cacheVal"; - msalCacheKey = browserSessionStorage.generateCacheKey("cacheKey"); - msalCacheKey2 = browserSessionStorage.generateCacheKey("cacheKey2"); - }); - - afterEach(async () => { - await browserSessionStorage.clear(); - await browserLocalStorage.clear(); - }); - - it("setTemporaryCache", () => { - browserSessionStorage.setTemporaryCache("cacheKey", cacheVal, true); - browserLocalStorage.setTemporaryCache("cacheKey2", cacheVal, true); - expect(window.sessionStorage.getItem(msalCacheKey)).toBe(cacheVal); - expect(window.localStorage.getItem(msalCacheKey2)).toBe(cacheVal); - }); - - it("getTemporaryCache returns value from localStorage", () => { - const testTempItemKey = "test-temp-item-key"; - const testTempItemValue = "test-temp-item-value"; - window.localStorage.setItem(testTempItemKey, testTempItemValue); - browserLocalStorage = new BrowserCacheManager( - TEST_CONFIG.MSAL_CLIENT_ID, - { - ...cacheConfig, - cacheLocation: BrowserCacheLocation.LocalStorage, - }, - browserCrypto, - logger, - new StubPerformanceClient(), - new EventHandler() - ); - expect(browserLocalStorage.getTemporaryCache(testTempItemKey)).toBe( - testTempItemValue - ); - }); - - it("removeItem()", () => { - browserSessionStorage.setTemporaryCache("cacheKey", cacheVal, true); - browserLocalStorage.setTemporaryCache("cacheKey", cacheVal, true); - browserSessionStorage.removeItem(msalCacheKey); - browserLocalStorage.removeItem(msalCacheKey); - expect(window.sessionStorage.getItem(msalCacheKey)).toBeNull(); - expect(window.localStorage.getItem(msalCacheKey)).toBeNull(); - expect( - browserLocalStorage.getTemporaryCache("cacheKey", true) - ).toBeNull(); - expect( - browserSessionStorage.getTemporaryCache("cacheKey", true) - ).toBeNull(); - }); - - it("clear()", async () => { - browserSessionStorage.setTemporaryCache("cacheKey", cacheVal, true); - browserLocalStorage.setTemporaryCache("cacheKey", cacheVal, true); - await browserSessionStorage.clear(); - await browserLocalStorage.clear(); - expect(browserSessionStorage.getKeys()).toHaveLength(0); - expect(browserLocalStorage.getKeys()).toHaveLength(0); - }); - - describe("Getters and Setters", () => { - describe("Account", () => { - it("getAccount returns null if key not in cache", () => { - const key = "not-in-cache"; - expect(browserSessionStorage.getAccount(key)).toBeNull(); - expect(browserLocalStorage.getAccount(key)).toBeNull(); - }); - - it("getAccount returns null if value is not JSON", () => { - const key = "testKey"; - window.localStorage.setItem(key, "this is not json"); - window.sessionStorage.setItem(key, "this is not json"); - - expect(browserSessionStorage.getAccount(key)).toBeNull(); - expect(browserLocalStorage.getAccount(key)).toBeNull(); - }); - - it("getAccount returns null if value is not account entity", () => { - const key = "testKey"; - const partialAccount = { - homeAccountId: "home-accountId", - }; - - window.localStorage.setItem( - key, - JSON.stringify(partialAccount) - ); - window.sessionStorage.setItem( - key, - JSON.stringify(partialAccount) - ); - - expect(browserSessionStorage.getAccount(key)).toBeNull(); - expect(browserLocalStorage.getAccount(key)).toBeNull(); - }); - - it("getAccount returns AccountEntity", async () => { - const testAccount = AccountEntityUtils.createAccountEntity( - { - homeAccountId: "homeAccountId", - idTokenClaims: AuthToken.extractTokenClaims( - TEST_TOKENS.IDTOKEN_V2, - base64Decode - ), - clientInfo: - TEST_DATA_CLIENT_INFO.TEST_RAW_CLIENT_INFO, - cloudGraphHostName: "cloudGraphHost", - msGraphHost: "msGraphHost", - }, - authority - ); - - await browserLocalStorage.setAccount( - testAccount, - TEST_CONFIG.CORRELATION_ID - ); - await browserSessionStorage.setAccount( - testAccount, - TEST_CONFIG.CORRELATION_ID - ); - - expect( - browserSessionStorage.getAccount( - AccountEntityUtils.generateAccountKey(testAccount) - ) - ).toEqual(testAccount); - expect( - AccountEntityUtils.isAccountEntity( - //@ts-ignore - browserSessionStorage.getAccount( - AccountEntityUtils.generateAccountKey( - testAccount - ) - ) - ) - ).toBe(true); - expect( - browserLocalStorage.getAccount( - AccountEntityUtils.generateAccountKey(testAccount) - ) - ).toEqual(testAccount); - expect( - AccountEntityUtils.isAccountEntity( - //@ts-ignore - browserLocalStorage.getAccount( - AccountEntityUtils.generateAccountKey( - testAccount - ) - ) - ) - ).toBe(true); - }); - }); - - describe("IdTokenCredential", () => { - it("getIdTokenCredential returns null if key not in cache", () => { - const key = "not-in-cache"; - expect( - browserSessionStorage.getIdTokenCredential(key) - ).toBeNull(); - expect( - browserLocalStorage.getIdTokenCredential(key) - ).toBeNull(); - }); - - it("getIdTokenCredential returns null if value is not JSON", () => { - const key = "testKey"; - window.localStorage.setItem(key, "this is not json"); - window.sessionStorage.setItem(key, "this is not json"); - - expect( - browserSessionStorage.getIdTokenCredential(key) - ).toBeNull(); - expect( - browserLocalStorage.getIdTokenCredential(key) - ).toBeNull(); - }); - - it("getIdTokenCredential returns null if value is not idToken entity", () => { - const key = "testKey"; - const partialIdTokenEntity = { - homeAccountId: "home-accountId", - }; - - window.localStorage.setItem( - key, - JSON.stringify(partialIdTokenEntity) - ); - window.sessionStorage.setItem( - key, - JSON.stringify(partialIdTokenEntity) - ); - - expect( - browserSessionStorage.getIdTokenCredential(key) - ).toBeNull(); - expect( - browserLocalStorage.getIdTokenCredential(key) - ).toBeNull(); - }); - - it("getIdTokenCredential returns IdTokenEntity", async () => { - const testIdToken = CacheHelpers.createIdTokenEntity( - "homeAccountId", - "environment", - TEST_TOKENS.IDTOKEN_V2, - "client-id", - "tenantId" - ); - - await browserLocalStorage.setIdTokenCredential( - testIdToken, - TEST_CONFIG.CORRELATION_ID - ); - await browserSessionStorage.setIdTokenCredential( - testIdToken, - TEST_CONFIG.CORRELATION_ID - ); - - expect( - browserSessionStorage.getIdTokenCredential( - CacheHelpers.generateCredentialKey(testIdToken) - ) - ).toEqual(testIdToken); - expect( - browserLocalStorage.getIdTokenCredential( - CacheHelpers.generateCredentialKey(testIdToken) - ) - ).toEqual(testIdToken); - }); - }); - - describe("AccessTokenCredential", () => { - it("getAccessTokenCredential returns null if key not in cache", () => { - const key = "not-in-cache"; - expect( - browserSessionStorage.getAccessTokenCredential(key) - ).toBeNull(); - expect( - browserLocalStorage.getAccessTokenCredential(key) - ).toBeNull(); - }); - - it("getAccessTokenCredential returns null if value is not JSON", () => { - const key = "testKey"; - window.localStorage.setItem(key, "this is not json"); - window.sessionStorage.setItem(key, "this is not json"); - - expect( - browserSessionStorage.getAccessTokenCredential(key) - ).toBeNull(); - expect( - browserLocalStorage.getAccessTokenCredential(key) - ).toBeNull(); - }); - - it("getAccessTokenCredential returns null if value is not accessToken entity", () => { - const key = "testKey"; - const partialAccessTokenEntity = { - homeAccountId: "home-accountId", - }; - - window.localStorage.setItem( - key, - JSON.stringify(partialAccessTokenEntity) - ); - window.sessionStorage.setItem( - key, - JSON.stringify(partialAccessTokenEntity) - ); - - expect( - browserSessionStorage.getAccessTokenCredential(key) - ).toBeNull(); - expect( - browserLocalStorage.getAccessTokenCredential(key) - ).toBeNull(); - }); - - it("getAccessTokenCredential returns AccessTokenEntity", async () => { - const testAccessToken = - CacheHelpers.createAccessTokenEntity( - "homeAccountId", - "environment", - TEST_TOKENS.ACCESS_TOKEN, - "client-id", - "tenantId", - "openid", - 1000, - 1000, - browserCrypto.base64Decode, - 500, - AuthenticationScheme.BEARER, - "oboAssertion" - ); - - await browserLocalStorage.setAccessTokenCredential( - testAccessToken, - TEST_CONFIG.CORRELATION_ID - ); - await browserSessionStorage.setAccessTokenCredential( - testAccessToken, - TEST_CONFIG.CORRELATION_ID - ); - - expect( - browserSessionStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey(testAccessToken) - ) - ).toEqual(testAccessToken); - expect( - browserLocalStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey(testAccessToken) - ) - ).toEqual(testAccessToken); - }); - - it("getAccessTokenCredential returns Bearer access token when authentication scheme is set to Bearer and both a Bearer and pop token are in the cache", async () => { - const testAccessTokenWithoutAuthScheme = - CacheHelpers.createAccessTokenEntity( - "homeAccountId", - "environment", - TEST_TOKENS.ACCESS_TOKEN, - "client-id", - "tenantId", - "openid", - 1000, - 1000, - browserCrypto.base64Decode, - 500, - AuthenticationScheme.BEARER, - "oboAssertion" - ); - const testAccessTokenWithAuthScheme = - CacheHelpers.createAccessTokenEntity( - "homeAccountId", - "environment", - TEST_TOKENS.POP_TOKEN, - "client-id", - "tenantId", - "openid", - 1000, - 1000, - browserCrypto.base64Decode, - 500, - AuthenticationScheme.POP, - "oboAssertion" - ); - // Cache bearer token - await browserLocalStorage.setAccessTokenCredential( - testAccessTokenWithoutAuthScheme, - TEST_CONFIG.CORRELATION_ID - ); - await browserSessionStorage.setAccessTokenCredential( - testAccessTokenWithoutAuthScheme, - TEST_CONFIG.CORRELATION_ID - ); - - // Cache pop token - await browserLocalStorage.setAccessTokenCredential( - testAccessTokenWithAuthScheme, - TEST_CONFIG.CORRELATION_ID - ); - await browserSessionStorage.setAccessTokenCredential( - testAccessTokenWithAuthScheme, - TEST_CONFIG.CORRELATION_ID - ); - - expect( - browserSessionStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey( - testAccessTokenWithoutAuthScheme - ) - ) - ).toEqual(testAccessTokenWithoutAuthScheme); - expect( - browserSessionStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey( - testAccessTokenWithoutAuthScheme - ) - )?.credentialType - ).toBe(CredentialType.ACCESS_TOKEN); - expect( - browserLocalStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey( - testAccessTokenWithoutAuthScheme - ) - ) - ).toEqual(testAccessTokenWithoutAuthScheme); - expect( - browserLocalStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey( - testAccessTokenWithoutAuthScheme - ) - )?.credentialType - ).toBe(CredentialType.ACCESS_TOKEN); - }); - - it("getAccessTokenCredential returns PoP access token when authentication scheme is set to pop and both a Bearer and pop token are in the cache", async () => { - const testAccessTokenWithoutAuthScheme = - CacheHelpers.createAccessTokenEntity( - "homeAccountId", - "environment", - TEST_TOKENS.ACCESS_TOKEN, - "client-id", - "tenantId", - "openid", - 1000, - 1000, - browserCrypto.base64Decode, - 500, - AuthenticationScheme.BEARER, - "oboAssertion" - ); - const testAccessTokenWithAuthScheme = - CacheHelpers.createAccessTokenEntity( - "homeAccountId", - "environment", - TEST_TOKENS.POP_TOKEN, - "client-id", - "tenantId", - "openid", - 1000, - 1000, - browserCrypto.base64Decode, - 500, - AuthenticationScheme.POP, - "oboAssertion" - ); - // Cache bearer token - await browserLocalStorage.setAccessTokenCredential( - testAccessTokenWithoutAuthScheme, - TEST_CONFIG.CORRELATION_ID - ); - await browserSessionStorage.setAccessTokenCredential( - testAccessTokenWithoutAuthScheme, - TEST_CONFIG.CORRELATION_ID - ); - - // Cache pop token - await browserLocalStorage.setAccessTokenCredential( - testAccessTokenWithAuthScheme, - TEST_CONFIG.CORRELATION_ID - ); - await browserSessionStorage.setAccessTokenCredential( - testAccessTokenWithAuthScheme, - TEST_CONFIG.CORRELATION_ID - ); - - expect( - browserSessionStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey( - testAccessTokenWithAuthScheme - ) - ) - ).toEqual(testAccessTokenWithAuthScheme); - expect( - browserSessionStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey( - testAccessTokenWithAuthScheme - ) - )?.credentialType - ).toBe(CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME); - expect( - browserLocalStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey( - testAccessTokenWithAuthScheme - ) - ) - ).toEqual(testAccessTokenWithAuthScheme); - expect( - browserLocalStorage.getAccessTokenCredential( - CacheHelpers.generateCredentialKey( - testAccessTokenWithAuthScheme - ) - )?.credentialType - ).toBe(CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME); - }); - }); - - describe("RefreshTokenCredential", () => { - it("getRefreshTokenCredential returns null if key not in cache", () => { - const key = "not-in-cache"; - expect( - browserSessionStorage.getRefreshTokenCredential(key) - ).toBeNull(); - expect( - browserLocalStorage.getRefreshTokenCredential(key) - ).toBeNull(); - }); - - it("getRefreshTokenCredential returns null if value is not JSON", () => { - const key = "testKey"; - window.localStorage.setItem(key, "this is not json"); - window.sessionStorage.setItem(key, "this is not json"); - - expect( - browserSessionStorage.getRefreshTokenCredential(key) - ).toBeNull(); - expect( - browserLocalStorage.getRefreshTokenCredential(key) - ).toBeNull(); - }); - - it("getRefreshTokenCredential returns null if value is not refreshToken entity", () => { - const key = "testKey"; - const partialRefreshTokenEntity = { - homeAccountId: "home-accountId", - }; - - window.localStorage.setItem( - key, - JSON.stringify(partialRefreshTokenEntity) - ); - window.sessionStorage.setItem( - key, - JSON.stringify(partialRefreshTokenEntity) - ); - - expect( - browserSessionStorage.getRefreshTokenCredential(key) - ).toBeNull(); - expect( - browserLocalStorage.getRefreshTokenCredential(key) - ).toBeNull(); - }); - - it("getRefreshTokenCredential returns RefreshTokenEntity", async () => { - const testRefreshToken = - CacheHelpers.createRefreshTokenEntity( - "homeAccountId", - "environment", - TEST_TOKENS.REFRESH_TOKEN, - "client-id", - "familyId", - "oboAssertion" - ); - - await browserLocalStorage.setRefreshTokenCredential( - testRefreshToken, - TEST_CONFIG.CORRELATION_ID - ); - await browserSessionStorage.setRefreshTokenCredential( - testRefreshToken, - TEST_CONFIG.CORRELATION_ID - ); - - expect( - browserSessionStorage.getRefreshTokenCredential( - CacheHelpers.generateCredentialKey(testRefreshToken) - ) - ).toEqual(testRefreshToken); - expect( - browserLocalStorage.getRefreshTokenCredential( - CacheHelpers.generateCredentialKey(testRefreshToken) - ) - ).toEqual(testRefreshToken); - }); - }); - - describe("AppMetadata", () => { - it("getAppMetadata returns null if key not in cache", () => { - const key = "not-in-cache"; - expect( - browserSessionStorage.getAppMetadata(key) - ).toBeNull(); - expect(browserLocalStorage.getAppMetadata(key)).toBeNull(); - }); - - it("getAppMetadata returns null if value is not JSON", () => { - const key = "testKey"; - window.localStorage.setItem(key, "this is not json"); - window.sessionStorage.setItem(key, "this is not json"); - - expect( - browserSessionStorage.getAppMetadata(key) - ).toBeNull(); - expect(browserLocalStorage.getAppMetadata(key)).toBeNull(); - }); - - it("getAppMetadata returns null if value is not appMetadata entity", () => { - const key = "testKey"; - const partialAppMetadataEntity = { - environment: "environment", - }; - - window.localStorage.setItem( - key, - JSON.stringify(partialAppMetadataEntity) - ); - window.sessionStorage.setItem( - key, - JSON.stringify(partialAppMetadataEntity) - ); - - expect( - browserSessionStorage.getAppMetadata(key) - ).toBeNull(); - expect(browserLocalStorage.getAppMetadata(key)).toBeNull(); - }); - - it("getAppMetadata returns AppMetadataEntity", () => { - const testAppMetadata = { - clientId: TEST_CONFIG.MSAL_CLIENT_ID, - environment: "login.microsoftonline.com", - familyId: "1", - }; - - browserLocalStorage.setAppMetadata(testAppMetadata); - browserSessionStorage.setAppMetadata(testAppMetadata); - - expect( - browserSessionStorage.getAppMetadata( - CacheHelpers.generateAppMetadataKey(testAppMetadata) - ) - ).toEqual(testAppMetadata); - expect( - browserLocalStorage.getAppMetadata( - CacheHelpers.generateAppMetadataKey(testAppMetadata) - ) - ).toEqual(testAppMetadata); - }); - }); - - describe("ServerTelemetry", () => { - it("getServerTelemetry returns null if key not in cache", () => { - const key = "not-in-cache"; - expect( - browserSessionStorage.getServerTelemetry(key) - ).toBeNull(); - expect( - browserLocalStorage.getServerTelemetry(key) - ).toBeNull(); - }); - - it("getServerTelemetry returns null if value is not JSON", () => { - const key = "testKey"; - window.localStorage.setItem(key, "this is not json"); - window.sessionStorage.setItem(key, "this is not json"); - - expect( - browserSessionStorage.getServerTelemetry(key) - ).toBeNull(); - expect( - browserLocalStorage.getServerTelemetry(key) - ).toBeNull(); - }); - - it("getServerTelemetry returns null if value is not serverTelemetry entity", () => { - const key = "testKey"; - const partialServerTelemetryEntity = { - apiId: 0, - }; - - window.localStorage.setItem( - key, - JSON.stringify(partialServerTelemetryEntity) - ); - window.sessionStorage.setItem( - key, - JSON.stringify(partialServerTelemetryEntity) - ); - - expect( - browserSessionStorage.getServerTelemetry(key) - ).toBeNull(); - expect( - browserLocalStorage.getServerTelemetry(key) - ).toBeNull(); - }); - - it("getServerTelemetry returns ServerTelemetryEntity", () => { - const testKey = "server-telemetry-clientId"; - const testVal = { - failedRequests: ["61|test-correlationId"], - errors: ["test_error"], - cacheHits: 2, - }; - - browserLocalStorage.setServerTelemetry(testKey, testVal); - browserSessionStorage.setServerTelemetry(testKey, testVal); - - expect( - browserSessionStorage.getServerTelemetry(testKey) - ).toEqual(testVal); - expect( - browserLocalStorage.getServerTelemetry(testKey) - ).toEqual(testVal); - }); - }); - - describe("AuthorityMetadata", () => { - const key = `authority-metadata-${TEST_CONFIG.MSAL_CLIENT_ID}-${Constants.DEFAULT_AUTHORITY_HOST}`; - const testObj: AuthorityMetadataEntity = { - aliases: [Constants.DEFAULT_AUTHORITY_HOST], - preferred_cache: Constants.DEFAULT_AUTHORITY_HOST, - preferred_network: Constants.DEFAULT_AUTHORITY_HOST, - canonical_authority: Constants.DEFAULT_AUTHORITY, - authorization_endpoint: - //@ts-ignore - DEFAULT_OPENID_CONFIG_RESPONSE.body - .authorization_endpoint, - token_endpoint: - //@ts-ignore - DEFAULT_OPENID_CONFIG_RESPONSE.body.token_endpoint, - end_session_endpoint: - //@ts-ignore - DEFAULT_OPENID_CONFIG_RESPONSE.body - .end_session_endpoint, - issuer: - //@ts-ignore - DEFAULT_OPENID_CONFIG_RESPONSE.body.issuer, - jwks_uri: - //@ts-ignore - DEFAULT_OPENID_CONFIG_RESPONSE.body.jwks_uri, - aliasesFromNetwork: false, - endpointsFromNetwork: false, - expiresAt: - CacheHelpers.generateAuthorityMetadataExpiresAt(), - }; - - it("getAuthorityMetadata() returns null if key is not in cache", () => { - expect( - browserSessionStorage.getAuthorityMetadata(key) - ).toBeNull(); - expect( - browserLocalStorage.getAuthorityMetadata(key) - ).toBeNull(); - }); - - it("getAuthorityMetadata() returns null if isAuthorityMetadataEntity returns false", () => { - browserSessionStorage.setAuthorityMetadata(key, { - // @ts-ignore - invalidKey: "invalidValue", - }); - browserLocalStorage.setAuthorityMetadata(key, { - // @ts-ignore - invalidKey: "invalidValue", - }); - - expect( - browserSessionStorage.getAuthorityMetadata(key) - ).toBeNull(); - expect( - browserLocalStorage.getAuthorityMetadata(key) - ).toBeNull(); - expect( - browserLocalStorage.getAuthorityMetadataKeys() - ).toEqual(expect.arrayContaining([key])); - expect( - browserSessionStorage.getAuthorityMetadataKeys() - ).toEqual(expect.arrayContaining([key])); - }); - - it("setAuthorityMetadata() and getAuthorityMetadata() sets and returns AuthorityMetadataEntity in-memory", () => { - browserSessionStorage.setAuthorityMetadata(key, testObj); - browserLocalStorage.setAuthorityMetadata(key, testObj); - - expect( - browserSessionStorage.getAuthorityMetadata(key) - ).toEqual(testObj); - expect( - browserLocalStorage.getAuthorityMetadata(key) - ).toEqual(testObj); - expect( - browserLocalStorage.getAuthorityMetadataKeys() - ).toEqual(expect.arrayContaining([key])); - expect( - browserSessionStorage.getAuthorityMetadataKeys() - ).toEqual(expect.arrayContaining([key])); - }); - - it("clear() removes AuthorityMetadataEntity from in-memory storage", async () => { - browserSessionStorage.setAuthorityMetadata(key, testObj); - browserLocalStorage.setAuthorityMetadata(key, testObj); - - expect( - browserSessionStorage.getAuthorityMetadata(key) - ).toEqual(testObj); - expect( - browserLocalStorage.getAuthorityMetadata(key) - ).toEqual(testObj); - expect( - browserLocalStorage.getAuthorityMetadataKeys() - ).toEqual(expect.arrayContaining([key])); - expect( - browserSessionStorage.getAuthorityMetadataKeys() - ).toEqual(expect.arrayContaining([key])); - - await browserSessionStorage.clear(); - await browserLocalStorage.clear(); - expect( - browserSessionStorage.getAuthorityMetadata(key) - ).toBeNull(); - expect( - browserLocalStorage.getAuthorityMetadata(key) - ).toBeNull(); - expect( - browserLocalStorage.getAuthorityMetadataKeys().length - ).toBe(0); - expect( - browserSessionStorage.getAuthorityMetadataKeys().length - ).toBe(0); - }); - }); - - describe("ThrottlingCache", () => { - it("getThrottlingCache returns null if key not in cache", () => { - const key = "not-in-cache"; - expect( - browserSessionStorage.getServerTelemetry(key) - ).toBeNull(); - expect( - browserLocalStorage.getServerTelemetry(key) - ).toBeNull(); - }); - - it("getThrottlingCache returns null if value is not JSON", () => { - const key = "testKey"; - window.localStorage.setItem(key, "this is not json"); - window.sessionStorage.setItem(key, "this is not json"); - - expect( - browserSessionStorage.getThrottlingCache(key) - ).toBeNull(); - expect( - browserLocalStorage.getThrottlingCache(key) - ).toBeNull(); - }); - - it("getThrottlingCache returns null if value is not throttling entity", () => { - const key = "testKey"; - const partialThrottlingEntity = { - error: "error", - }; - - window.localStorage.setItem( - key, - JSON.stringify(partialThrottlingEntity) - ); - window.sessionStorage.setItem( - key, - JSON.stringify(partialThrottlingEntity) - ); - - expect( - browserSessionStorage.getThrottlingCache(key) - ).toBeNull(); - expect( - browserLocalStorage.getThrottlingCache(key) - ).toBeNull(); - }); - - it("getThrottlingCache returns ThrottlingEntity", () => { - const testKey = "throttling"; - const testVal = { throttleTime: 60 }; - - browserLocalStorage.setThrottlingCache(testKey, testVal); - browserSessionStorage.setThrottlingCache(testKey, testVal); - - expect( - browserSessionStorage.getThrottlingCache(testKey) - ).toEqual(testVal); - expect( - browserLocalStorage.getThrottlingCache(testKey) - ).toEqual(testVal); - }); - }); - }); - }); - describe("Helpers", () => { it("resetTempCacheItems() resets all temporary cache items with the given state", () => { const browserStorage = new BrowserCacheManager( diff --git a/lib/msal-browser/test/cache/TokenCache.spec.ts b/lib/msal-browser/test/cache/TokenCache.spec.ts index c2c6314648..e8b679e0a2 100644 --- a/lib/msal-browser/test/cache/TokenCache.spec.ts +++ b/lib/msal-browser/test/cache/TokenCache.spec.ts @@ -62,9 +62,7 @@ describe("TokenCache tests", () => { true ); cacheConfig = { - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - claimsBasedCachingEnabled: false, }; logger = new Logger({ loggerCallback: ( diff --git a/lib/msal-browser/test/config/Configuration.spec.ts b/lib/msal-browser/test/config/Configuration.spec.ts index d7b9b93db1..90ab472e02 100644 --- a/lib/msal-browser/test/config/Configuration.spec.ts +++ b/lib/msal-browser/test/config/Configuration.spec.ts @@ -52,7 +52,6 @@ describe("Configuration.ts Class Unit Tests", () => { expect(emptyConfig.cache).toBeDefined(); expect(emptyConfig.cache?.cacheLocation).toBeDefined(); expect(emptyConfig.cache?.cacheLocation).toBe("sessionStorage"); - expect(emptyConfig.cache?.claimsBasedCachingEnabled).toBe(false); // System config checks expect(emptyConfig.system).toBeDefined(); expect(emptyConfig.system?.loggerOptions).toBeDefined(); @@ -240,7 +239,6 @@ describe("Configuration.ts Class Unit Tests", () => { }, cache: { cacheLocation: BrowserCacheLocation.LocalStorage, - claimsBasedCachingEnabled: true, }, system: { windowHashTimeout: TEST_POPUP_TIMEOUT_MS, @@ -269,7 +267,6 @@ describe("Configuration.ts Class Unit Tests", () => { expect(newConfig.cache).not.toBeNull(); expect(newConfig.cache?.cacheLocation).not.toBeNull(); expect(newConfig.cache?.cacheLocation).toBe("localStorage"); - expect(newConfig.cache?.claimsBasedCachingEnabled).toBe(true); // System config checks expect(newConfig.system).not.toBeNull(); expect(newConfig.system?.windowHashTimeout).not.toBeNull(); diff --git a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts index bf009f6ea9..2551188c68 100644 --- a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts +++ b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts @@ -92,8 +92,6 @@ import { BrowserPerformanceClient } from "../../src/telemetry/BrowserPerformance const cacheConfig = { cacheLocation: BrowserCacheLocation.SessionStorage, - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - claimsBasedCachingEnabled: false, }; const testRequest: CommonAuthorizationUrlRequest = { diff --git a/lib/msal-browser/test/request/RequestHelpers.spec.ts b/lib/msal-browser/test/request/RequestHelpers.spec.ts new file mode 100644 index 0000000000..eeb92bdc8f --- /dev/null +++ b/lib/msal-browser/test/request/RequestHelpers.spec.ts @@ -0,0 +1,139 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { + AuthenticationScheme, + BaseAuthRequest, + ClientConfigurationError, + ClientConfigurationErrorCodes, + Logger, + StubPerformanceClient +} from "@azure/msal-common"; +// import { +// initializeBaseRequest, +// initializeSilentRequest, +// } from "../../src/request/RequestHelpers.js"; +import * as RequestHelpers from "../../src/request/RequestHelpers.js"; +import { BrowserConfiguration } from "../../src/config/Configuration.js"; +import { SilentRequest } from "../../src/request/SilentRequest.js"; + +describe("RequestHelpers tests", () => { + let mockConfig: BrowserConfiguration; + let mockPerformanceClient: any; + let mockLogger: Logger; + + beforeEach(() => { + mockConfig = { + auth: { + authority: "https://login.microsoftonline.com/common", + }, + } as BrowserConfiguration; + + mockPerformanceClient = new StubPerformanceClient(); + + mockLogger = new Logger({}); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + describe("initializeBaseRequest", () => { + it("should initialize a base request with default values", async () => { + const request: Partial & { correlationId: string } = { + correlationId: "test-correlation-id", + scopes: ["User.Read"], + }; + + const result = await RequestHelpers.initializeBaseRequest( + request, + mockConfig, + mockPerformanceClient, + mockLogger + ); + + expect(result.correlationId).toBe("test-correlation-id"); + expect(result.scopes).toEqual(["User.Read"]); + expect(result.authority).toBe("https://login.microsoftonline.com/common"); + expect(result.authenticationScheme).toBe(AuthenticationScheme.BEARER); + }); + + it("should throw an error if SSH authentication scheme is used without sshJwk", async () => { + const request: Partial & { correlationId: string } = { + correlationId: "test-correlation-id", + authenticationScheme: AuthenticationScheme.SSH, + }; + + await expect( + RequestHelpers.initializeBaseRequest(request, mockConfig, mockPerformanceClient, mockLogger) + ).rejects.toThrowError( + new ClientConfigurationError(ClientConfigurationErrorCodes.missingSshJwk) + ); + }); + + it("should set requestedClaimsHash if claims are provided", async () => { + const request: Partial & { correlationId: string } = { + correlationId: "test-correlation-id", + claims: '{"access_token":{"xms_cc":{"values":["cp1"]}}}', + }; + + const result = await RequestHelpers.initializeBaseRequest( + request, + mockConfig, + mockPerformanceClient, + mockLogger + ); + + expect(result.requestedClaimsHash).toBeDefined(); + }); + + it("should not set requestedClaimsHash if claims are empty stringified object", async () => { + const request: Partial & { correlationId: string } = { + correlationId: "test-correlation-id", + claims: '{}', + }; + + const result = await RequestHelpers.initializeBaseRequest( + request, + mockConfig, + mockPerformanceClient, + mockLogger + ); + + expect(result.requestedClaimsHash).not.toBeDefined(); + }); + }); + + describe("initializeSilentRequest", () => { + it("should initialize a silent request with default values", async () => { + const request: SilentRequest & { correlationId: string } = { + correlationId: "test-correlation-id", + scopes: ["User.Read"], + forceRefresh: true, + }; + + const account = { + homeAccountId: "test-home-account-id", + environment: "login.microsoftonline.com", + tenantId: "test-tenant-id", + username: "test-user", + localAccountId: "test-local-account-id", + }; + + const result = await RequestHelpers.initializeSilentRequest( + request, + account, + mockConfig, + mockPerformanceClient, + mockLogger + ); + + expect(result.correlationId).toBe("test-correlation-id"); + expect(result.scopes).toEqual(["User.Read"]); + expect(result.account).toEqual(account); + expect(result.forceRefresh).toBe(true); + }); + }); +}); \ No newline at end of file diff --git a/lib/msal-common/src/client/SilentFlowClient.ts b/lib/msal-common/src/client/SilentFlowClient.ts index 0801c88ee0..17e4b830fd 100644 --- a/lib/msal-common/src/client/SilentFlowClient.ts +++ b/lib/msal-common/src/client/SilentFlowClient.ts @@ -46,9 +46,7 @@ export class SilentFlowClient extends BaseClient { let lastCacheOutcome: CacheOutcome = CacheOutcome.NOT_APPLICABLE; if ( - request.forceRefresh || - (!this.config.cacheOptions.claimsBasedCachingEnabled && - !StringUtils.isEmptyObj(request.claims)) + request.forceRefresh || !StringUtils.isEmptyObj(request.claims) ) { // Must refresh due to present force_refresh flag. this.setCacheOutcome( diff --git a/lib/msal-common/src/config/ClientConfiguration.ts b/lib/msal-common/src/config/ClientConfiguration.ts index 03ad4d03d8..7a32d7a19b 100644 --- a/lib/msal-common/src/config/ClientConfiguration.ts +++ b/lib/msal-common/src/config/ClientConfiguration.ts @@ -59,7 +59,7 @@ export type CommonClientConfiguration = { authOptions: Required; systemOptions: Required; loggerOptions: Required; - cacheOptions: Required; + cacheOptions: CacheOptions | undefined; storageInterface: CacheManager; networkInterface: INetworkModule; cryptoInterface: Required; @@ -120,14 +120,9 @@ export type LoggerOptions = { /** * Use this to configure credential cache preferences in the ClientConfiguration object - * - * - claimsBasedCachingEnabled - Sets whether tokens should be cached based on the claims hash. Default is false. */ export type CacheOptions = { - /** - * @deprecated claimsBasedCachingEnabled is deprecated and will be removed in the next major version. - */ - claimsBasedCachingEnabled?: boolean; + }; /** @@ -179,10 +174,6 @@ const DEFAULT_LOGGER_IMPLEMENTATION: Required = { correlationId: Constants.EMPTY_STRING, }; -const DEFAULT_CACHE_OPTIONS: Required = { - claimsBasedCachingEnabled: false, -}; - const DEFAULT_NETWORK_IMPLEMENTATION: INetworkModule = { async sendGetRequestAsync(): Promise { throw createClientAuthError(ClientAuthErrorCodes.methodNotImplemented); @@ -247,7 +238,7 @@ export function buildClientConfiguration({ authOptions: buildAuthOptions(userAuthOptions), systemOptions: { ...DEFAULT_SYSTEM_OPTIONS, ...userSystemOptions }, loggerOptions: loggerOptions, - cacheOptions: { ...DEFAULT_CACHE_OPTIONS, ...userCacheOptions }, + cacheOptions: undefined, storageInterface: storageImplementation || new DefaultStorageClass( diff --git a/lib/msal-common/test/client/SilentFlowClient.spec.ts b/lib/msal-common/test/client/SilentFlowClient.spec.ts index 340c5c6149..74def04491 100644 --- a/lib/msal-common/test/client/SilentFlowClient.spec.ts +++ b/lib/msal-common/test/client/SilentFlowClient.spec.ts @@ -365,72 +365,6 @@ describe("SilentFlowClient unit tests", () => { ); }); - it("acquireCachedToken does not throw when given valid claims with claimsBasedCachingEnabled", async () => { - const testScopes = [ - Constants.OPENID_SCOPE, - Constants.PROFILE_SCOPE, - ...TEST_CONFIG.DEFAULT_GRAPH_SCOPE, - ]; - testAccessTokenEntity.target = testScopes.join(" "); - jest.spyOn( - Authority.prototype, - "getEndpointMetadataFromNetwork" - ).mockResolvedValue(DEFAULT_OPENID_CONFIG_RESPONSE.body); - jest.spyOn( - CacheManager.prototype, - "readAccountFromCache" - ).mockReturnValue(testAccountEntity); - jest.spyOn(CacheManager.prototype, "getIdToken").mockReturnValue( - testIdToken - ); - jest.spyOn( - CacheManager.prototype, - "getAccessToken" - ).mockReturnValue(testAccessTokenEntity); - jest.spyOn( - CacheManager.prototype, - "getRefreshToken" - ).mockReturnValue(testRefreshTokenEntity); - const config = - await ClientTestUtils.createTestClientConfiguration(); - const client = new SilentFlowClient( - { - ...config, - cacheOptions: { - ...config.cacheOptions, - claimsBasedCachingEnabled: true, - }, - }, - stubPerformanceClient - ); - jest.spyOn(TimeUtils, "isTokenExpired").mockReturnValue(false); - - const silentFlowRequest: CommonSilentFlowRequest = { - scopes: TEST_CONFIG.DEFAULT_GRAPH_SCOPE, - account: testAccount, - authority: TEST_CONFIG.validAuthority, - correlationId: TEST_CONFIG.CORRELATION_ID, - forceRefresh: false, - claims: `{ "access_token": { "xms_cc":{"values":["cp1"] } }}`, - }; - - const response = await client.acquireCachedToken(silentFlowRequest); - const authResult: AuthenticationResult = response[0]; - expect(authResult.authority).toEqual( - `${TEST_URIS.DEFAULT_INSTANCE}${TEST_CONFIG.TENANT}/` - ); - expect(authResult.uniqueId).toEqual(ID_TOKEN_CLAIMS.oid); - expect(authResult.tenantId).toEqual(ID_TOKEN_CLAIMS.tid); - expect(authResult.scopes).toEqual(testScopes); - expect(authResult.account).toEqual(testAccount); - expect(authResult.idToken).toEqual(testIdToken.secret); - expect(authResult.idTokenClaims).toEqual(ID_TOKEN_CLAIMS); - expect(authResult.accessToken).toEqual( - testAccessTokenEntity.secret - ); - expect(authResult.state).toBe(""); - }); - it("acquireCachedToken returns correct token when max age is provided and has not transpired yet", async () => { const testScopes = [ Constants.OPENID_SCOPE, diff --git a/lib/msal-common/test/config/ClientConfiguration.spec.ts b/lib/msal-common/test/config/ClientConfiguration.spec.ts index 9b846f4376..a2352435e9 100644 --- a/lib/msal-common/test/config/ClientConfiguration.spec.ts +++ b/lib/msal-common/test/config/ClientConfiguration.spec.ts @@ -108,8 +108,7 @@ describe("ClientConfiguration.ts Class Unit Tests", () => { expect(emptyConfig.loggerOptions).not.toBeNull(); expect(emptyConfig.loggerOptions.piiLoggingEnabled).toBe(false); // Cache Options checks - expect(emptyConfig.cacheOptions).not.toBeNull(); - expect(emptyConfig.cacheOptions.claimsBasedCachingEnabled).toBe(false); + expect(emptyConfig.cacheOptions).toBeUndefined(); // Client info checks expect(emptyConfig.libraryInfo.sku).toBe(Constants.SKU); expect(emptyConfig.libraryInfo.version).toBe(version); @@ -203,9 +202,6 @@ describe("ClientConfiguration.ts Class Unit Tests", () => { ): void => {}, piiLoggingEnabled: true, }, - cacheOptions: { - claimsBasedCachingEnabled: true, - }, libraryInfo: { sku: TEST_CONFIG.TEST_SKU, version: TEST_CONFIG.TEST_VERSION, @@ -274,8 +270,7 @@ describe("ClientConfiguration.ts Class Unit Tests", () => { expect(newConfig.loggerOptions.loggerCallback).not.toBeNull(); expect(newConfig.loggerOptions.piiLoggingEnabled).toBe(true); // Cache options tests - expect(newConfig.cacheOptions).not.toBeNull(); - expect(newConfig.cacheOptions.claimsBasedCachingEnabled).toBe(true); + expect(newConfig.cacheOptions).toBeUndefined(); // Client info tests expect(newConfig.libraryInfo.sku).toBe(TEST_CONFIG.TEST_SKU); expect(newConfig.libraryInfo.version).toBe(TEST_CONFIG.TEST_VERSION); diff --git a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/testConfig.json b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/testConfig.json index 03e2e663d2..eb120a7590 100644 --- a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/testConfig.json +++ b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/testConfig.json @@ -1 +1,19 @@ -{"msalConfig":{"auth":{"clientId":"b5c2e510-4a17-4feb-b219-e55aa5b74144","authority":"https://login.microsoftonline.com/common"},"cache":{"cacheLocation":"memoryStorage","storeAuthStateInCookie":true},"system":{"allowPlatformBroker":false}},"request":{"scopes":["User.Read"]}} \ No newline at end of file +{ + "msalConfig": { + "auth": { + "clientId": "b5c2e510-4a17-4feb-b219-e55aa5b74144", + "authority": "https://login.microsoftonline.com/common" + }, + "cache": { + "cacheLocation": "memoryStorage" + }, + "system": { + "allowPlatformBroker": false + } + }, + "request": { + "scopes": [ + "User.Read" + ] + } +} \ No newline at end of file From a3fb3fc45a050f219092d9d1805f434cacdc6e51 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Wed, 23 Apr 2025 12:23:26 -0700 Subject: [PATCH 12/24] Format and lint --- .../test/request/RequestHelpers.spec.ts | 41 ++++++++++++++----- .../src/client/SilentFlowClient.ts | 4 +- .../src/config/ClientConfiguration.ts | 6 +-- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/lib/msal-browser/test/request/RequestHelpers.spec.ts b/lib/msal-browser/test/request/RequestHelpers.spec.ts index eeb92bdc8f..20ab1a1c3a 100644 --- a/lib/msal-browser/test/request/RequestHelpers.spec.ts +++ b/lib/msal-browser/test/request/RequestHelpers.spec.ts @@ -9,7 +9,7 @@ import { ClientConfigurationError, ClientConfigurationErrorCodes, Logger, - StubPerformanceClient + StubPerformanceClient, } from "@azure/msal-common"; // import { // initializeBaseRequest, @@ -42,7 +42,9 @@ describe("RequestHelpers tests", () => { describe("initializeBaseRequest", () => { it("should initialize a base request with default values", async () => { - const request: Partial & { correlationId: string } = { + const request: Partial & { + correlationId: string; + } = { correlationId: "test-correlation-id", scopes: ["User.Read"], }; @@ -56,25 +58,40 @@ describe("RequestHelpers tests", () => { expect(result.correlationId).toBe("test-correlation-id"); expect(result.scopes).toEqual(["User.Read"]); - expect(result.authority).toBe("https://login.microsoftonline.com/common"); - expect(result.authenticationScheme).toBe(AuthenticationScheme.BEARER); + expect(result.authority).toBe( + "https://login.microsoftonline.com/common" + ); + expect(result.authenticationScheme).toBe( + AuthenticationScheme.BEARER + ); }); it("should throw an error if SSH authentication scheme is used without sshJwk", async () => { - const request: Partial & { correlationId: string } = { + const request: Partial & { + correlationId: string; + } = { correlationId: "test-correlation-id", authenticationScheme: AuthenticationScheme.SSH, }; await expect( - RequestHelpers.initializeBaseRequest(request, mockConfig, mockPerformanceClient, mockLogger) + RequestHelpers.initializeBaseRequest( + request, + mockConfig, + mockPerformanceClient, + mockLogger + ) ).rejects.toThrowError( - new ClientConfigurationError(ClientConfigurationErrorCodes.missingSshJwk) + new ClientConfigurationError( + ClientConfigurationErrorCodes.missingSshJwk + ) ); }); it("should set requestedClaimsHash if claims are provided", async () => { - const request: Partial & { correlationId: string } = { + const request: Partial & { + correlationId: string; + } = { correlationId: "test-correlation-id", claims: '{"access_token":{"xms_cc":{"values":["cp1"]}}}', }; @@ -90,9 +107,11 @@ describe("RequestHelpers tests", () => { }); it("should not set requestedClaimsHash if claims are empty stringified object", async () => { - const request: Partial & { correlationId: string } = { + const request: Partial & { + correlationId: string; + } = { correlationId: "test-correlation-id", - claims: '{}', + claims: "{}", }; const result = await RequestHelpers.initializeBaseRequest( @@ -136,4 +155,4 @@ describe("RequestHelpers tests", () => { expect(result.forceRefresh).toBe(true); }); }); -}); \ No newline at end of file +}); diff --git a/lib/msal-common/src/client/SilentFlowClient.ts b/lib/msal-common/src/client/SilentFlowClient.ts index 17e4b830fd..bb96119126 100644 --- a/lib/msal-common/src/client/SilentFlowClient.ts +++ b/lib/msal-common/src/client/SilentFlowClient.ts @@ -45,9 +45,7 @@ export class SilentFlowClient extends BaseClient { ); let lastCacheOutcome: CacheOutcome = CacheOutcome.NOT_APPLICABLE; - if ( - request.forceRefresh || !StringUtils.isEmptyObj(request.claims) - ) { + if (request.forceRefresh || !StringUtils.isEmptyObj(request.claims)) { // Must refresh due to present force_refresh flag. this.setCacheOutcome( CacheOutcome.FORCE_REFRESH_OR_CLAIMS, diff --git a/lib/msal-common/src/config/ClientConfiguration.ts b/lib/msal-common/src/config/ClientConfiguration.ts index 7a32d7a19b..0b01c37fc3 100644 --- a/lib/msal-common/src/config/ClientConfiguration.ts +++ b/lib/msal-common/src/config/ClientConfiguration.ts @@ -121,9 +121,7 @@ export type LoggerOptions = { /** * Use this to configure credential cache preferences in the ClientConfiguration object */ -export type CacheOptions = { - -}; +export type CacheOptions = {}; /** * Library-specific options @@ -238,7 +236,7 @@ export function buildClientConfiguration({ authOptions: buildAuthOptions(userAuthOptions), systemOptions: { ...DEFAULT_SYSTEM_OPTIONS, ...userSystemOptions }, loggerOptions: loggerOptions, - cacheOptions: undefined, + cacheOptions: userCacheOptions || undefined, storageInterface: storageImplementation || new DefaultStorageClass( From 9e89fb9c980c54ef570ce61d4cde7ef9780c8ff0 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Wed, 23 Apr 2025 12:25:21 -0700 Subject: [PATCH 13/24] Update apiExtractor --- lib/msal-browser/apiReview/msal-browser.api.md | 4 +--- lib/msal-common/apiReview/msal-common.api.md | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/msal-browser/apiReview/msal-browser.api.md b/lib/msal-browser/apiReview/msal-browser.api.md index 9bd335527a..1fb402aa8b 100644 --- a/lib/msal-browser/apiReview/msal-browser.api.md +++ b/lib/msal-browser/apiReview/msal-browser.api.md @@ -408,8 +408,6 @@ export type CacheLookupPolicy = (typeof CacheLookupPolicy)[keyof typeof CacheLoo // @public export type CacheOptions = { cacheLocation?: BrowserCacheLocation | string; - temporaryCacheLocation?: BrowserCacheLocation | string; - claimsBasedCachingEnabled?: boolean; }; // Warning: (ae-missing-release-tag) "ClearCacheRequest" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1489,7 +1487,7 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU]; // src/cache/LocalStorage.ts:296:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:354:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:385:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/config/Configuration.ts:256:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts +// src/config/Configuration.ts:211:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts // src/event/EventHandler.ts:113:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/event/EventHandler.ts:139:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" diff --git a/lib/msal-common/apiReview/msal-common.api.md b/lib/msal-common/apiReview/msal-common.api.md index cca1651662..c281f31f63 100644 --- a/lib/msal-common/apiReview/msal-common.api.md +++ b/lib/msal-common/apiReview/msal-common.api.md @@ -1163,9 +1163,7 @@ export abstract class CacheManager implements ICacheManager { // Warning: (ae-missing-release-tag) "CacheOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export type CacheOptions = { - claimsBasedCachingEnabled?: boolean; -}; +export type CacheOptions = {}; // Warning: (ae-missing-release-tag) "CacheOutcome" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "CacheOutcome" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -4415,7 +4413,7 @@ const X_MS_LIB_CAPABILITY = "x-ms-lib-capability"; // src/client/RefreshTokenClient.ts:287:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/client/RefreshTokenClient.ts:288:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/client/RefreshTokenClient.ts:339:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/client/SilentFlowClient.ts:172:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/client/SilentFlowClient.ts:168:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/config/ClientConfiguration.ts:50:5 - (ae-forgotten-export) The symbol "ClientCredentials" needs to be exported by the entry point index.d.ts // src/config/ClientConfiguration.ts:52:5 - (ae-forgotten-export) The symbol "TelemetryOptions" needs to be exported by the entry point index.d.ts // src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" From 79e0a3485da96ecde00232cb6c2c3f924c1a2dc2 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Tue, 29 Apr 2025 16:04:13 -0700 Subject: [PATCH 14/24] Update tests for not caching claims --- .../test/app/PublicClientApplication.spec.ts | 23 +++++++++++++++++++ .../test/cache/BrowserCacheManager.spec.ts | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/msal-browser/test/app/PublicClientApplication.spec.ts b/lib/msal-browser/test/app/PublicClientApplication.spec.ts index 49745b4261..1df2b9f4a1 100644 --- a/lib/msal-browser/test/app/PublicClientApplication.spec.ts +++ b/lib/msal-browser/test/app/PublicClientApplication.spec.ts @@ -577,6 +577,29 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { expect(preGenerateSpy).toHaveBeenCalledTimes(1); }); + + it("clears previous cache with claims", async () => { + const preGenerateSpy = jest.spyOn( + BrowserCacheManager.prototype, + // @ts-ignore + "clearTokensAndKeysWithClaims" + ); + + pca = new PublicClientApplication({ + auth: { + clientId: TEST_CONFIG.MSAL_CLIENT_ID, + }, + system: { + allowPlatformBroker: false, + }, + }); + await pca.initialize(); + + //Implementation of PCA was moved to controller. + pca = (pca as any).controller; + + expect(preGenerateSpy).toHaveBeenCalledTimes(1); + }); }); describe("handleRedirectPromise", () => { diff --git a/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts b/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts index c90c1802a0..239972cbbe 100644 --- a/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts +++ b/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts @@ -720,7 +720,7 @@ describe("BrowserCacheManager tests", () => { ).toBe(CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME); }); - it("clearTokensWithClaimsInCache clears all access tokens with claims in tokenKeys", async () => { + it("clearTokensAndKeysWithClaims clears all access tokens with claims in tokenKeys", async () => { const testAT1 = CacheHelpers.createAccessTokenEntity( "homeAccountId1", "environment", From 00a3f90d7ca67c24e06a51287f8fdd81e756f6ed Mon Sep 17 00:00:00 2001 From: joarroyo Date: Fri, 2 May 2025 11:22:43 -0700 Subject: [PATCH 15/24] Remove e2e test for redirects with memory storage as not supported --- .../test/browserMemStorage.spec.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/test/browserMemStorage.spec.ts b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/test/browserMemStorage.spec.ts index c5efcc1e82..fa083dba1a 100644 --- a/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/test/browserMemStorage.spec.ts +++ b/samples/msal-browser-samples/VanillaJSTestApp2.0/app/customizable-e2e-test/test/browserMemStorage.spec.ts @@ -99,19 +99,6 @@ describe("In Memory Storage Tests", function () { await page.close(); }); - it("Performs loginRedirect", async () => { - const testName = "redirectBaseCase"; - const screenshot = new Screenshot( - `${SCREENSHOT_BASE_FOLDER_NAME}/${testName}` - ); - - await clickLoginRedirect(screenshot, page); - await enterCredentials(page, screenshot, username, accountPwd); - await waitForReturnToApp(screenshot, page); - // Verify browser cache contains Account, idToken, AccessToken and RefreshToken - await verifyTokenStore(BrowserCache, memStorageTokenRequest.scopes); - }); - it("Performs loginPopup", async () => { const testName = "popupBaseCase"; const screenshot = new Screenshot( From 5864f6c8e60609dfc9cc4cf26e107c0f839c2fcf Mon Sep 17 00:00:00 2001 From: Jo Arroyo Date: Fri, 2 May 2025 12:41:21 -0700 Subject: [PATCH 16/24] Update lib/msal-browser/docs/caching.md Co-authored-by: Thomas Norling --- lib/msal-browser/docs/caching.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msal-browser/docs/caching.md b/lib/msal-browser/docs/caching.md index 10b6b41466..ff8ed2f1cd 100644 --- a/lib/msal-browser/docs/caching.md +++ b/lib/msal-browser/docs/caching.md @@ -66,7 +66,7 @@ To faciliate efficient token acquisition while maintaining a good UX, MSAL cache - previous failed request - performance data -> :bulb: Temporary cache entries will always be stored in session storage or in memory. MSAL will fallback to memory storage if local/session storage is not available. Please read the warning below for more information. +> :bulb: Temporary cache entries will always be stored in session storage or in memory. MSAL will fallback to memory storage if sessionStorage is not available. > :bulb: The authorization code is only stored in memory and will be discarded after redeeming it for tokens. From 35cb31455f468db95c15b8a15e22aa860c1a8e99 Mon Sep 17 00:00:00 2001 From: joarroyo Date: Fri, 2 May 2025 15:21:52 -0700 Subject: [PATCH 17/24] Remove CacheOptions as empty --- lib/msal-common/src/config/ClientConfiguration.ts | 9 ++------- lib/msal-common/src/exports-common.ts | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/msal-common/src/config/ClientConfiguration.ts b/lib/msal-common/src/config/ClientConfiguration.ts index a03975a128..3e2fd6561c 100644 --- a/lib/msal-common/src/config/ClientConfiguration.ts +++ b/lib/msal-common/src/config/ClientConfiguration.ts @@ -43,7 +43,7 @@ export type ClientConfiguration = { authOptions: AuthOptions; systemOptions?: SystemOptions; loggerOptions?: LoggerOptions; - cacheOptions?: CacheOptions; + cacheOptions?: undefined; storageInterface?: CacheManager; networkInterface?: INetworkModule; cryptoInterface?: ICrypto; @@ -59,7 +59,7 @@ export type CommonClientConfiguration = { authOptions: Required; systemOptions: Required; loggerOptions: Required; - cacheOptions: CacheOptions | undefined; + cacheOptions: undefined; storageInterface: CacheManager; networkInterface: INetworkModule; cryptoInterface: Required; @@ -118,11 +118,6 @@ export type LoggerOptions = { correlationId?: string; }; -/** - * Use this to configure credential cache preferences in the ClientConfiguration object - */ -export type CacheOptions = {}; - /** * Library-specific options */ diff --git a/lib/msal-common/src/exports-common.ts b/lib/msal-common/src/exports-common.ts index c70f71e162..95492e1fc9 100644 --- a/lib/msal-common/src/exports-common.ts +++ b/lib/msal-common/src/exports-common.ts @@ -27,7 +27,6 @@ export { AuthOptions, SystemOptions, LoggerOptions, - CacheOptions, DEFAULT_SYSTEM_OPTIONS, AzureCloudOptions, ApplicationTelemetry, From 4ccb22be6194b7d205f76365b1181bc7d7048cb6 Mon Sep 17 00:00:00 2001 From: Jo Arroyo Date: Fri, 9 May 2025 13:04:36 -0700 Subject: [PATCH 18/24] Remove setting requestedClaimsHash with claimsBasedCachingEnabled flag --- .../src/request/RequestHelpers.ts | 9 ----- .../test/request/RequestHelpers.spec.ts | 36 ------------------- 2 files changed, 45 deletions(-) diff --git a/lib/msal-browser/src/request/RequestHelpers.ts b/lib/msal-browser/src/request/RequestHelpers.ts index 36884dda11..efcae81061 100644 --- a/lib/msal-browser/src/request/RequestHelpers.ts +++ b/lib/msal-browser/src/request/RequestHelpers.ts @@ -71,15 +71,6 @@ export async function initializeBaseRequest( ); } - // Set requested claims hash if claims were requested - if ( - request.claims && - // Checks for empty stringified object "{}" which doesn't qualify as requested claims - !StringUtils.isEmptyObj(request.claims) - ) { - validatedRequest.requestedClaimsHash = await hashString(request.claims); - } - return validatedRequest; } diff --git a/lib/msal-browser/test/request/RequestHelpers.spec.ts b/lib/msal-browser/test/request/RequestHelpers.spec.ts index 20ab1a1c3a..a56a0f4dc3 100644 --- a/lib/msal-browser/test/request/RequestHelpers.spec.ts +++ b/lib/msal-browser/test/request/RequestHelpers.spec.ts @@ -87,42 +87,6 @@ describe("RequestHelpers tests", () => { ) ); }); - - it("should set requestedClaimsHash if claims are provided", async () => { - const request: Partial & { - correlationId: string; - } = { - correlationId: "test-correlation-id", - claims: '{"access_token":{"xms_cc":{"values":["cp1"]}}}', - }; - - const result = await RequestHelpers.initializeBaseRequest( - request, - mockConfig, - mockPerformanceClient, - mockLogger - ); - - expect(result.requestedClaimsHash).toBeDefined(); - }); - - it("should not set requestedClaimsHash if claims are empty stringified object", async () => { - const request: Partial & { - correlationId: string; - } = { - correlationId: "test-correlation-id", - claims: "{}", - }; - - const result = await RequestHelpers.initializeBaseRequest( - request, - mockConfig, - mockPerformanceClient, - mockLogger - ); - - expect(result.requestedClaimsHash).not.toBeDefined(); - }); }); describe("initializeSilentRequest", () => { From 8ac724921a4f59b8ec7fab48129a1931d9825ad8 Mon Sep 17 00:00:00 2001 From: Jo Arroyo Date: Fri, 9 May 2025 13:21:44 -0700 Subject: [PATCH 19/24] Fix linting --- lib/msal-browser/src/request/RequestHelpers.ts | 2 -- lib/msal-browser/test/request/RequestHelpers.spec.ts | 4 ---- 2 files changed, 6 deletions(-) diff --git a/lib/msal-browser/src/request/RequestHelpers.ts b/lib/msal-browser/src/request/RequestHelpers.ts index efcae81061..f987eea68e 100644 --- a/lib/msal-browser/src/request/RequestHelpers.ts +++ b/lib/msal-browser/src/request/RequestHelpers.ts @@ -12,13 +12,11 @@ import { IPerformanceClient, Logger, PerformanceEvents, - StringUtils, createClientConfigurationError, invokeAsync, } from "@azure/msal-common/browser"; import { BrowserConfiguration } from "../config/Configuration.js"; import { SilentRequest } from "./SilentRequest.js"; -import { hashString } from "../crypto/BrowserCrypto.js"; /** * Initializer function for all request APIs diff --git a/lib/msal-browser/test/request/RequestHelpers.spec.ts b/lib/msal-browser/test/request/RequestHelpers.spec.ts index a56a0f4dc3..7e86c68004 100644 --- a/lib/msal-browser/test/request/RequestHelpers.spec.ts +++ b/lib/msal-browser/test/request/RequestHelpers.spec.ts @@ -11,10 +11,6 @@ import { Logger, StubPerformanceClient, } from "@azure/msal-common"; -// import { -// initializeBaseRequest, -// initializeSilentRequest, -// } from "../../src/request/RequestHelpers.js"; import * as RequestHelpers from "../../src/request/RequestHelpers.js"; import { BrowserConfiguration } from "../../src/config/Configuration.js"; import { SilentRequest } from "../../src/request/SilentRequest.js"; From 9b68a2b6735d46b6d38febea6b63c7ed469e6cbc Mon Sep 17 00:00:00 2001 From: Jo Arroyo Date: Tue, 20 May 2025 11:35:18 -0700 Subject: [PATCH 20/24] apiExtractor --- lib/msal-browser/apiReview/msal-browser.api.md | 2 +- lib/msal-common/apiReview/msal-common.api.md | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/msal-browser/apiReview/msal-browser.api.md b/lib/msal-browser/apiReview/msal-browser.api.md index d1d03b6afc..db5179ce72 100644 --- a/lib/msal-browser/apiReview/msal-browser.api.md +++ b/lib/msal-browser/apiReview/msal-browser.api.md @@ -1496,7 +1496,7 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU]; // src/cache/LocalStorage.ts:296:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:354:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:385:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/config/Configuration.ts:231:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts +// src/config/Configuration.ts:211:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts // src/event/EventHandler.ts:113:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/event/EventHandler.ts:139:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" diff --git a/lib/msal-common/apiReview/msal-common.api.md b/lib/msal-common/apiReview/msal-common.api.md index 56a7cc84ae..fad91efd5f 100644 --- a/lib/msal-common/apiReview/msal-common.api.md +++ b/lib/msal-common/apiReview/msal-common.api.md @@ -1160,11 +1160,6 @@ export abstract class CacheManager implements ICacheManager { static toObject(obj: T, json: object): T; } -// Warning: (ae-missing-release-tag) "CacheOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export type CacheOptions = {}; - // Warning: (ae-missing-release-tag) "CacheOutcome" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "CacheOutcome" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1464,7 +1459,7 @@ export type ClientConfiguration = { authOptions: AuthOptions; systemOptions?: SystemOptions; loggerOptions?: LoggerOptions; - cacheOptions?: CacheOptions; + cacheOptions?: undefined; storageInterface?: CacheManager; networkInterface?: INetworkModule; cryptoInterface?: ICrypto; From 347e280f4f49059b1a9a97e626afb51f0aee04a2 Mon Sep 17 00:00:00 2001 From: Jo Arroyo Date: Wed, 21 May 2025 10:15:54 -0700 Subject: [PATCH 21/24] Address feedback --- lib/msal-common/src/config/ClientConfiguration.ts | 3 --- lib/msal-common/test/config/ClientConfiguration.spec.ts | 4 ---- 2 files changed, 7 deletions(-) diff --git a/lib/msal-common/src/config/ClientConfiguration.ts b/lib/msal-common/src/config/ClientConfiguration.ts index 3e2fd6561c..1cf1839b40 100644 --- a/lib/msal-common/src/config/ClientConfiguration.ts +++ b/lib/msal-common/src/config/ClientConfiguration.ts @@ -59,7 +59,6 @@ export type CommonClientConfiguration = { authOptions: Required; systemOptions: Required; loggerOptions: Required; - cacheOptions: undefined; storageInterface: CacheManager; networkInterface: INetworkModule; cryptoInterface: Required; @@ -211,7 +210,6 @@ export function buildClientConfiguration({ authOptions: userAuthOptions, systemOptions: userSystemOptions, loggerOptions: userLoggerOption, - cacheOptions: userCacheOptions, storageInterface: storageImplementation, networkInterface: networkImplementation, cryptoInterface: cryptoImplementation, @@ -231,7 +229,6 @@ export function buildClientConfiguration({ authOptions: buildAuthOptions(userAuthOptions), systemOptions: { ...DEFAULT_SYSTEM_OPTIONS, ...userSystemOptions }, loggerOptions: loggerOptions, - cacheOptions: userCacheOptions || undefined, storageInterface: storageImplementation || new DefaultStorageClass( diff --git a/lib/msal-common/test/config/ClientConfiguration.spec.ts b/lib/msal-common/test/config/ClientConfiguration.spec.ts index a2352435e9..9dc671e90d 100644 --- a/lib/msal-common/test/config/ClientConfiguration.spec.ts +++ b/lib/msal-common/test/config/ClientConfiguration.spec.ts @@ -107,8 +107,6 @@ describe("ClientConfiguration.ts Class Unit Tests", () => { // Logger options checks expect(emptyConfig.loggerOptions).not.toBeNull(); expect(emptyConfig.loggerOptions.piiLoggingEnabled).toBe(false); - // Cache Options checks - expect(emptyConfig.cacheOptions).toBeUndefined(); // Client info checks expect(emptyConfig.libraryInfo.sku).toBe(Constants.SKU); expect(emptyConfig.libraryInfo.version).toBe(version); @@ -269,8 +267,6 @@ describe("ClientConfiguration.ts Class Unit Tests", () => { expect(newConfig.loggerOptions).not.toBeNull(); expect(newConfig.loggerOptions.loggerCallback).not.toBeNull(); expect(newConfig.loggerOptions.piiLoggingEnabled).toBe(true); - // Cache options tests - expect(newConfig.cacheOptions).toBeUndefined(); // Client info tests expect(newConfig.libraryInfo.sku).toBe(TEST_CONFIG.TEST_SKU); expect(newConfig.libraryInfo.version).toBe(TEST_CONFIG.TEST_VERSION); From aa2455f3ba55710909467871a5f9839411ff0c0b Mon Sep 17 00:00:00 2001 From: Jo Arroyo Date: Wed, 21 May 2025 12:15:50 -0700 Subject: [PATCH 22/24] Remove cacheOptions on ClientConfiguration --- lib/msal-common/src/config/ClientConfiguration.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/msal-common/src/config/ClientConfiguration.ts b/lib/msal-common/src/config/ClientConfiguration.ts index 1cf1839b40..0f39f3dfc7 100644 --- a/lib/msal-common/src/config/ClientConfiguration.ts +++ b/lib/msal-common/src/config/ClientConfiguration.ts @@ -43,7 +43,6 @@ export type ClientConfiguration = { authOptions: AuthOptions; systemOptions?: SystemOptions; loggerOptions?: LoggerOptions; - cacheOptions?: undefined; storageInterface?: CacheManager; networkInterface?: INetworkModule; cryptoInterface?: ICrypto; From 20441feea9252fbfda919d2644e2018fcd620659 Mon Sep 17 00:00:00 2001 From: Jo Arroyo Date: Wed, 21 May 2025 12:17:05 -0700 Subject: [PATCH 23/24] apiExtractor --- lib/msal-common/apiReview/msal-common.api.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/msal-common/apiReview/msal-common.api.md b/lib/msal-common/apiReview/msal-common.api.md index b7ac86fe0c..5a873c10de 100644 --- a/lib/msal-common/apiReview/msal-common.api.md +++ b/lib/msal-common/apiReview/msal-common.api.md @@ -1401,7 +1401,6 @@ export type ClientConfiguration = { authOptions: AuthOptions; systemOptions?: SystemOptions; loggerOptions?: LoggerOptions; - cacheOptions?: undefined; storageInterface?: CacheManager; networkInterface?: INetworkModule; cryptoInterface?: ICrypto; @@ -4325,8 +4324,8 @@ const X_MS_LIB_CAPABILITY = "x-ms-lib-capability"; // src/client/RefreshTokenClient.ts:288:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/client/RefreshTokenClient.ts:339:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/client/SilentFlowClient.ts:168:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/config/ClientConfiguration.ts:50:5 - (ae-forgotten-export) The symbol "ClientCredentials" needs to be exported by the entry point index.d.ts -// src/config/ClientConfiguration.ts:52:5 - (ae-forgotten-export) The symbol "TelemetryOptions" needs to be exported by the entry point index.d.ts +// src/config/ClientConfiguration.ts:49:5 - (ae-forgotten-export) The symbol "ClientCredentials" needs to be exported by the entry point index.d.ts +// src/config/ClientConfiguration.ts:51:5 - (ae-forgotten-export) The symbol "TelemetryOptions" needs to be exported by the entry point index.d.ts // src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" // src/index.ts:8:4 - (tsdoc-undefined-tag) The TSDoc tag "@module" is not defined in this configuration // src/request/AuthenticationHeaderParser.ts:74:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen From a30d08c6458b8dfec59b54f6020b17271103545c Mon Sep 17 00:00:00 2001 From: Jo Arroyo Date: Wed, 21 May 2025 14:07:25 -0700 Subject: [PATCH 24/24] Remove reference to claimsBasedCachingEnabled in new error doc --- docs/errors.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/errors.md b/docs/errors.md index ccbdc4d61f..c20d4b484f 100644 --- a/docs/errors.md +++ b/docs/errors.md @@ -18,7 +18,6 @@ This error occurs when MSAL.js surpasses the allotted storage limit when attempt **Mitigation**: 1. Make sure the configured cache storage has enough capacity to allow MSAL.js to persist token payload. The amount of cache storage required depends on the number of [cached artifacts](./caching.md#cached-artifacts). -2. Disable [claimsBasedCachingEnabled](./configuration.md#cache-config-options) cache config option. When enabled, it caches access tokens under a key containing the hash of the requested claims. Depending on the MSAL.js API usage, it may result in the vast number of access tokens persisted in the cache storage. ### `cache_error_unknown` - An unknown error occurred while accessing the browser cache.