Skip to content

Commit 8313d0b

Browse files
authored
Merge branch 'dev' into dependency-updates
2 parents 44f5d81 + b24a122 commit 8313d0b

7 files changed

Lines changed: 112 additions & 7 deletions
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Preserve authority metadata when calling clear() [#8542](https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/8542)",
4+
"packageName": "@azure/msal-node",
5+
"email": "shylasummers@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

lib/msal-node/src/cache/NodeStorage.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ export class NodeStorage extends CacheManager {
500500
}
501501

502502
/**
503-
* Clears all cache entries created by MSAL (except tokens).
503+
* Clears all cache entries created by MSAL except authority metadata..
504504
*/
505505
clear(): void {
506506
this.logger.trace("Clearing cache entries created by MSAL", "");
@@ -510,6 +510,9 @@ export class NodeStorage extends CacheManager {
510510

511511
// delete each element
512512
cacheKeys.forEach((key) => {
513+
if (this.isAuthorityMetadata(key)) {
514+
return;
515+
}
513516
this.removeItem(key);
514517
});
515518
this.emitChange();

lib/msal-node/src/client/ClientApplication.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ export abstract class ClientApplication {
675675
}
676676

677677
/**
678-
* Clear the cache
678+
* Clear the cache except for authority metadata.
679679
*/
680680
clearCache(): void {
681681
this.storage.clear();

lib/msal-node/src/client/IConfidentialClientApplication.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export interface IConfidentialClientApplication {
6767
/** Replaces the default logger set in configurations with new Logger with new configurations */
6868
setLogger(logger: Logger): void;
6969

70-
/** Clear the cache */
70+
/** Clear the cache except for authority metadata. */
7171
clearCache(): void;
7272

7373
/** This extensibility point is meant for Azure SDK to enhance Managed Identity support */

lib/msal-node/src/client/IPublicClientApplication.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export interface IPublicClientApplication {
6868
/** Replaces the default logger set in configurations with new Logger with new configurations */
6969
setLogger(logger: Logger): void;
7070

71-
/** Clear the cache */
71+
/** Clear the cache except for authority metadata, which is not included in the serialized cache and would otherwise be lost. */
7272
clearCache(): void;
7373

7474
/** Gets all cached accounts */

lib/msal-node/test/cache/Storage.spec.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,22 +366,52 @@ describe("Storage tests for msal-node: ", () => {
366366
expect(newInMemoryCache.accounts[ACCOUNT_KEY]).toBeUndefined;
367367
});
368368

369-
it("should remove all keys from the cache when clear() is called", () => {
369+
it("clear() removes all cache entries except authority metadata", () => {
370370
const nodeStorage = new NodeStorage(
371371
logger,
372372
clientId,
373373
DEFAULT_CRYPTO_IMPLEMENTATION
374374
);
375375
nodeStorage.setInMemoryCache(inMemoryCache);
376376

377-
nodeStorage.clear();
377+
const host = "login.microsoftonline.com";
378+
const authorityMetadataKey = `authority-metadata-${clientId}-${host}`;
379+
const authorityMetadata: AuthorityMetadataEntity = {
380+
aliases: [host],
381+
preferred_cache: host,
382+
preferred_network: host,
383+
canonical_authority: TEST_CONSTANTS.DEFAULT_AUTHORITY,
384+
authorization_endpoint:
385+
DEFAULT_OPENID_CONFIG_RESPONSE.body.authorization_endpoint,
386+
token_endpoint: DEFAULT_OPENID_CONFIG_RESPONSE.body.token_endpoint,
387+
end_session_endpoint:
388+
DEFAULT_OPENID_CONFIG_RESPONSE.body.end_session_endpoint,
389+
issuer: DEFAULT_OPENID_CONFIG_RESPONSE.body.issuer,
390+
jwks_uri: DEFAULT_OPENID_CONFIG_RESPONSE.body.jwks_uri,
391+
aliasesFromNetwork: false,
392+
endpointsFromNetwork: false,
393+
expiresAt: CacheHelpers.generateAuthorityMetadataExpiresAt(),
394+
};
395+
nodeStorage.setAuthorityMetadata(
396+
authorityMetadataKey,
397+
authorityMetadata
398+
);
378399

379-
expect(nodeStorage.getAccount(ACCOUNT_KEY)).toBeNull();
400+
nodeStorage.clear();
380401

402+
// Token/account/appMetadata entries should be cleared
381403
const newInMemoryCache = nodeStorage.getInMemoryCache();
382404
Object.values(newInMemoryCache).forEach((cacheSection) => {
383405
expect(cacheSection).toEqual({});
384406
});
407+
408+
// Authority metadata should be preserved
409+
expect(nodeStorage.getAuthorityMetadata(authorityMetadataKey)).toEqual(
410+
authorityMetadata
411+
);
412+
expect(nodeStorage.getAuthorityMetadataKeys()).toContain(
413+
authorityMetadataKey
414+
);
385415
});
386416

387417
describe("Getters and Setters", () => {

lib/msal-node/test/cache/TokenCache.spec.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ICachePlugin,
1111
buildStaticAuthorityOptions,
1212
Constants,
13+
AuthorityMetadataEntity,
1314
} from "@azure/msal-common";
1415
import { NodeStorage } from "../../src/cache/NodeStorage.js";
1516
import { TokenCache } from "../../src/cache/TokenCache.js";
@@ -283,6 +284,70 @@ describe("TokenCache tests", () => {
283284
);
284285
});
285286

287+
it("overwriteCache should preserve authority metadata", async () => {
288+
const cachePath = "./test/cache/cache-test-files/default-cache.json";
289+
const beforeCacheAccess = async (context: TokenCacheContext) => {
290+
context.tokenCache.deserialize(
291+
await promises.readFile(cachePath, Constants.EncodingTypes.UTF8)
292+
);
293+
};
294+
const afterCacheAccess = async (context: TokenCacheContext) => {
295+
await promises.writeFile(cachePath, context.tokenCache.serialize());
296+
};
297+
298+
const cachePlugin: ICachePlugin = {
299+
beforeCacheAccess,
300+
afterCacheAccess,
301+
};
302+
303+
const tokenCache = new TokenCache(storage, logger, cachePlugin);
304+
305+
// Populate authority metadata in the storage before overwriting
306+
const authorityMetadataKey =
307+
"authority-metadata-mock_client_id-login.microsoftonline.com";
308+
const authorityMetadata = {
309+
aliases: [
310+
"login.microsoftonline.com",
311+
"login.windows.net",
312+
"login.microsoft.com",
313+
],
314+
preferred_cache: "login.windows.net",
315+
preferred_network: "login.microsoftonline.com",
316+
canonical_authority: "https://login.microsoftonline.com/common",
317+
authorization_endpoint:
318+
"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
319+
token_endpoint:
320+
"https://login.microsoftonline.com/common/oauth2/v2.0/token",
321+
end_session_endpoint:
322+
"https://login.microsoftonline.com/common/oauth2/v2.0/logout",
323+
issuer: "https://login.microsoftonline.com/{tenantid}/v2.0",
324+
jwks_uri:
325+
"https://login.microsoftonline.com/common/discovery/v2.0/keys",
326+
aliasesFromNetwork: true,
327+
endpointsFromNetwork: true,
328+
expiresAt:
329+
msalCommon.CacheHelpers.generateAuthorityMetadataExpiresAt(),
330+
};
331+
storage.setAuthorityMetadata(
332+
authorityMetadataKey,
333+
authorityMetadata as AuthorityMetadataEntity
334+
);
335+
336+
expect(storage.getAuthorityMetadata(authorityMetadataKey)).toEqual(
337+
authorityMetadata
338+
);
339+
340+
await tokenCache.overwriteCache();
341+
342+
const restoredMetadata =
343+
storage.getAuthorityMetadata(authorityMetadataKey);
344+
expect(restoredMetadata).not.toBeNull();
345+
expect(restoredMetadata!.aliases).toEqual(authorityMetadata.aliases);
346+
expect(restoredMetadata!.preferred_cache).toEqual(
347+
authorityMetadata.preferred_cache
348+
);
349+
});
350+
286351
it("overwriteCache should not throw and simply return if persistent cache does not exist", async () => {
287352
const tokenCache = new TokenCache(storage, logger);
288353

0 commit comments

Comments
 (0)