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/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" +} diff --git a/docs/errors.md b/docs/errors.md index ada30cda39..1a317af193 100644 --- a/docs/errors.md +++ b/docs/errors.md @@ -17,8 +17,7 @@ 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](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser/docs/caching.md#cached-artifacts). -2. Disable [claimsBasedCachingEnabled](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser/docs/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. +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). ### `cache_error_unknown` - An unknown error occurred while accessing the browser cache. diff --git a/lib/msal-angular/docs/configuration.md b/lib/msal-angular/docs/configuration.md index f33e0face6..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, // Deprecated, will be removed in the next major version }, 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 933056e374..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, // Deprecated, will be removed in future version }, system: { loggerOptions: { @@ -115,7 +114,6 @@ import { PublicClientApplication, InteractionType, BrowserCacheLocation } from " }, cache: { cacheLocation : BrowserCacheLocation.LocalStorage, - storeAuthStateInCookie: true, // Deprecated, will be removed in future version }, system: { loggerOptions: { diff --git a/lib/msal-browser/apiReview/msal-browser.api.md b/lib/msal-browser/apiReview/msal-browser.api.md index 5a09228041..7cc30cf571 100644 --- a/lib/msal-browser/apiReview/msal-browser.api.md +++ b/lib/msal-browser/apiReview/msal-browser.api.md @@ -403,10 +403,6 @@ export type CacheLookupPolicy = (typeof CacheLookupPolicy)[keyof typeof CacheLoo // @public export type CacheOptions = { cacheLocation?: BrowserCacheLocation | string; - temporaryCacheLocation?: BrowserCacheLocation | string; - storeAuthStateInCookie?: boolean; - cacheMigrationEnabled?: boolean; - 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) @@ -1491,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: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-browser/docs/caching.md b/lib/msal-browser/docs/caching.md index 34ae27b430..ff8ed2f1cd 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 sessionStorage is not available. > :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 d77bc7c650..c65257e8a7 100644 --- a/lib/msal-browser/docs/configuration.md +++ b/lib/msal-browser/docs/configuration.md @@ -22,10 +22,6 @@ const msalConfig = { }, cache: { cacheLocation: "sessionStorage", - temporaryCacheLocation: "sessionStorage", - storeAuthStateInCookie: false, - secureCookies: false, - claimsBasedCachingEnabled: true, }, system: { loggerOptions: { @@ -96,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/src/cache/BrowserCacheManager.ts b/lib/msal-browser/src/cache/BrowserCacheManager.ts index 0f271f56dd..f296f4c9a7 100644 --- a/lib/msal-browser/src/cache/BrowserCacheManager.ts +++ b/lib/msal-browser/src/cache/BrowserCacheManager.ts @@ -70,8 +70,6 @@ import { clearHash } from "../utils/BrowserUtils.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. @@ -112,7 +110,7 @@ export class BrowserCacheManager extends CacheManager { ); this.temporaryCacheStorage = getStorageImplementation( clientId, - cacheConfig.temporaryCacheLocation, + BrowserCacheLocation.SessionStorage, logger, performanceClient ); @@ -890,21 +888,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 @@ -933,8 +920,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 */ @@ -944,14 +929,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); - } } /** @@ -964,17 +942,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); - } } /** @@ -1385,10 +1356,6 @@ export const DEFAULT_BROWSER_CACHE_MANAGER = ( ): BrowserCacheManager => { const cacheOptions: Required = { cacheLocation: BrowserCacheLocation.MemoryStorage, - temporaryCacheLocation: BrowserCacheLocation.MemoryStorage, - storeAuthStateInCookie: false, - cacheMigrationEnabled: false, - 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 6830703903..876b0043b2 100644 --- a/lib/msal-browser/src/config/Configuration.ts +++ b/lib/msal-browser/src/config/Configuration.ts @@ -113,26 +113,6 @@ export type CacheOptions = { * Used to specify the cacheLocation user wants to set. Valid values are "localStorage", "sessionStorage" and "memoryStorage". */ cacheLocation?: BrowserCacheLocation | string; - /** - * 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; - /** - * 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. - * @deprecated This option is deprecated and will be removed in the next major version. - */ - 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. - * @deprecated This option is deprecated and will be removed in the next major version. - */ - cacheMigrationEnabled?: boolean; - /** - * 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 & { @@ -282,15 +262,6 @@ export function buildConfiguration( // Default cache options for browser 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 && - userInputCache.cacheLocation === BrowserCacheLocation.LocalStorage - ? true - : false, - 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 5952b15b1c..817aefdc3b 100644 --- a/lib/msal-browser/src/controllers/StandardController.ts +++ b/lib/msal-browser/src/controllers/StandardController.ts @@ -261,10 +261,6 @@ export class StandardController implements IController { // initialize in memory storage for native flows const nativeCacheOptions: Required = { cacheLocation: BrowserCacheLocation.MemoryStorage, - temporaryCacheLocation: BrowserCacheLocation.MemoryStorage, - storeAuthStateInCookie: false, - cacheMigrationEnabled: false, - claimsBasedCachingEnabled: false, }; this.nativeInternalStorage = new BrowserCacheManager( this.config.auth.clientId, @@ -374,21 +370,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..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 @@ -71,16 +69,6 @@ export async function initializeBaseRequest( ); } - // Set requested claims hash if claims-based caching is enabled and 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) - ) { - validatedRequest.requestedClaimsHash = await hashString(request.claims); - } - return validatedRequest; } diff --git a/lib/msal-browser/src/utils/BrowserUtils.ts b/lib/msal-browser/src/utils/BrowserUtils.ts index a2b69a0d48..d1d6e4b8cf 100644 --- a/lib/msal-browser/src/utils/BrowserUtils.ts +++ b/lib/msal-browser/src/utils/BrowserUtils.ts @@ -175,11 +175,8 @@ export function redirectPreflightCheck( ): void { preflightCheck(initialized); blockRedirectInIframe(config.system.allowRedirectInIframe); - // Block redirects if memory storage is enabled but storeAuthStateInCookie is not - if ( - config.cache.cacheLocation === BrowserCacheLocation.MemoryStorage && - !config.cache.storeAuthStateInCookie - ) { + // Block redirects if memory storage is enabled + if (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 61b68d6b55..f6d2e1751e 100644 --- a/lib/msal-browser/test/app/PublicClientApplication.spec.ts +++ b/lib/msal-browser/test/app/PublicClientApplication.spec.ts @@ -122,11 +122,7 @@ import { PlatformAuthDOMHandler } from "../../src/broker/nativeBroker/PlatformAu import { config } from "process"; const cacheConfig = { - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, - cacheMigrationEnabled: false, - claimsBasedCachingEnabled: false, }; let testAppConfig = { @@ -2047,14 +2043,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, @@ -4775,127 +4770,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, @@ -5097,270 +4971,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, @@ -7501,10 +7111,6 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { TEST_CONFIG.MSAL_CLIENT_ID, { cacheLocation: BrowserCacheLocation.LocalStorage, - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, - cacheMigrationEnabled: false, - 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 cdf8fdcac1..764a9f1483 100644 --- a/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts +++ b/lib/msal-browser/test/cache/BrowserCacheManager.spec.ts @@ -60,11 +60,7 @@ describe("BrowserCacheManager tests", () => { let browserCrypto: CryptoOps; beforeEach(() => { cacheConfig = { - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, - cacheMigrationEnabled: false, - claimsBasedCachingEnabled: false, }; logger = new Logger({ loggerCallback: ( @@ -725,7 +721,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", @@ -1564,1237 +1560,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("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 d646f6d061..e8b679e0a2 100644 --- a/lib/msal-browser/test/cache/TokenCache.spec.ts +++ b/lib/msal-browser/test/cache/TokenCache.spec.ts @@ -62,11 +62,7 @@ describe("TokenCache tests", () => { true ); cacheConfig = { - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, cacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, - cacheMigrationEnabled: false, - 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 1bceb556f2..90ab472e02 100644 --- a/lib/msal-browser/test/config/Configuration.spec.ts +++ b/lib/msal-browser/test/config/Configuration.spec.ts @@ -52,9 +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(); expect(emptyConfig.system?.loggerOptions).toBeDefined(); @@ -242,8 +239,6 @@ describe("Configuration.ts Class Unit Tests", () => { }, cache: { cacheLocation: BrowserCacheLocation.LocalStorage, - storeAuthStateInCookie: true, - claimsBasedCachingEnabled: true, }, system: { windowHashTimeout: TEST_POPUP_TIMEOUT_MS, @@ -272,9 +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?.storeAuthStateInCookie).not.toBeNull(); - expect(newConfig.cache?.storeAuthStateInCookie).toBe(true); - 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 5403bd63ce..d838553069 100644 --- a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts +++ b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts @@ -92,10 +92,6 @@ import { BrowserPerformanceClient } from "../../src/telemetry/BrowserPerformance const cacheConfig = { cacheLocation: BrowserCacheLocation.SessionStorage, - temporaryCacheLocation: BrowserCacheLocation.SessionStorage, - storeAuthStateInCookie: false, - cacheMigrationEnabled: false, - 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..7e86c68004 --- /dev/null +++ b/lib/msal-browser/test/request/RequestHelpers.spec.ts @@ -0,0 +1,118 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { + AuthenticationScheme, + BaseAuthRequest, + ClientConfigurationError, + ClientConfigurationErrorCodes, + Logger, + StubPerformanceClient, +} from "@azure/msal-common"; +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 + ) + ); + }); + }); + + 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); + }); + }); +}); diff --git a/lib/msal-common/apiReview/msal-common.api.md b/lib/msal-common/apiReview/msal-common.api.md index cc6fd158cb..5a873c10de 100644 --- a/lib/msal-common/apiReview/msal-common.api.md +++ b/lib/msal-common/apiReview/msal-common.api.md @@ -1152,13 +1152,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 = { - claimsBasedCachingEnabled?: boolean; -}; - // 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) // @@ -1408,7 +1401,6 @@ export type ClientConfiguration = { authOptions: AuthOptions; systemOptions?: SystemOptions; loggerOptions?: LoggerOptions; - cacheOptions?: CacheOptions; storageInterface?: CacheManager; networkInterface?: INetworkModule; cryptoInterface?: ICrypto; @@ -4331,9 +4323,9 @@ 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/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/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: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 diff --git a/lib/msal-common/src/client/SilentFlowClient.ts b/lib/msal-common/src/client/SilentFlowClient.ts index 0801c88ee0..bb96119126 100644 --- a/lib/msal-common/src/client/SilentFlowClient.ts +++ b/lib/msal-common/src/client/SilentFlowClient.ts @@ -45,11 +45,7 @@ export class SilentFlowClient extends BaseClient { ); let lastCacheOutcome: CacheOutcome = CacheOutcome.NOT_APPLICABLE; - if ( - request.forceRefresh || - (!this.config.cacheOptions.claimsBasedCachingEnabled && - !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 7f17a5b8fc..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?: CacheOptions; storageInterface?: CacheManager; networkInterface?: INetworkModule; cryptoInterface?: ICrypto; @@ -59,7 +58,6 @@ export type CommonClientConfiguration = { authOptions: Required; systemOptions: Required; loggerOptions: Required; - cacheOptions: Required; storageInterface: CacheManager; networkInterface: INetworkModule; cryptoInterface: Required; @@ -118,18 +116,6 @@ export type LoggerOptions = { correlationId?: string; }; -/** - * 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; -}; - /** * Library-specific options */ @@ -179,10 +165,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); @@ -227,7 +209,6 @@ export function buildClientConfiguration({ authOptions: userAuthOptions, systemOptions: userSystemOptions, loggerOptions: userLoggerOption, - cacheOptions: userCacheOptions, storageInterface: storageImplementation, networkInterface: networkImplementation, cryptoInterface: cryptoImplementation, @@ -247,7 +228,6 @@ export function buildClientConfiguration({ authOptions: buildAuthOptions(userAuthOptions), systemOptions: { ...DEFAULT_SYSTEM_OPTIONS, ...userSystemOptions }, loggerOptions: loggerOptions, - cacheOptions: { ...DEFAULT_CACHE_OPTIONS, ...userCacheOptions }, storageInterface: storageImplementation || new DefaultStorageClass( diff --git a/lib/msal-common/src/exports-common.ts b/lib/msal-common/src/exports-common.ts index 944f11875f..c8376933fa 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, 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..9dc671e90d 100644 --- a/lib/msal-common/test/config/ClientConfiguration.spec.ts +++ b/lib/msal-common/test/config/ClientConfiguration.spec.ts @@ -107,9 +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).not.toBeNull(); - expect(emptyConfig.cacheOptions.claimsBasedCachingEnabled).toBe(false); // Client info checks expect(emptyConfig.libraryInfo.sku).toBe(Constants.SKU); expect(emptyConfig.libraryInfo.version).toBe(version); @@ -203,9 +200,6 @@ describe("ClientConfiguration.ts Class Unit Tests", () => { ): void => {}, piiLoggingEnabled: true, }, - cacheOptions: { - claimsBasedCachingEnabled: true, - }, libraryInfo: { sku: TEST_CONFIG.TEST_SKU, version: TEST_CONFIG.TEST_VERSION, @@ -273,9 +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).not.toBeNull(); - expect(newConfig.cacheOptions.claimsBasedCachingEnabled).toBe(true); // 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/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-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( 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 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/).