diff --git a/packages/zowe-explorer-api/__tests__/__unit__/profiles/AuthHandler.unit.test.ts b/packages/zowe-explorer-api/__tests__/__unit__/profiles/AuthHandler.unit.test.ts index 5b83c5575..05611f050 100644 --- a/packages/zowe-explorer-api/__tests__/__unit__/profiles/AuthHandler.unit.test.ts +++ b/packages/zowe-explorer-api/__tests__/__unit__/profiles/AuthHandler.unit.test.ts @@ -54,6 +54,23 @@ describe("AuthHandler.waitForUnlock", () => { }); }); +describe("AuthHandler.unlockAllProfiles", () => { + it("unlocks all profiles in the AuthHandler.profileLocks map", async () => { + const mutexAuthPrompt = new Mutex(); + const mutexProfile = new Mutex(); + const releaseAuthPromptMutex = jest.spyOn(mutexAuthPrompt, "release"); + const releaseProfileMutex = jest.spyOn(mutexProfile, "release"); + (AuthHandler as any).authPromptLocks.set(TEST_PROFILE_NAME, mutexAuthPrompt); + (AuthHandler as any).profileLocks.set(TEST_PROFILE_NAME, mutexProfile); + + AuthHandler.unlockAllProfiles(); + expect(releaseAuthPromptMutex).toHaveBeenCalledTimes(1); + expect(releaseProfileMutex).toHaveBeenCalledTimes(1); + (AuthHandler as any).authPromptLocks.clear(); + (AuthHandler as any).profileLocks.clear(); + }); +}); + describe("AuthHandler.isProfileLocked", () => { it("returns true if the profile is locked", async () => { await AuthHandler.lockProfile(TEST_PROFILE_NAME); diff --git a/packages/zowe-explorer-api/src/profiles/AuthHandler.ts b/packages/zowe-explorer-api/src/profiles/AuthHandler.ts index ff112e985..ef72dc3b3 100644 --- a/packages/zowe-explorer-api/src/profiles/AuthHandler.ts +++ b/packages/zowe-explorer-api/src/profiles/AuthHandler.ts @@ -245,6 +245,21 @@ export class AuthHandler { } } + /** + * Releases locks for all profiles. + * Used for scenarios such as the `onVaultChanged` event, where we don't know what secure values have changed, + * but we can't assume that the profile still has invalid credentials. + */ + public static unlockAllProfiles(): void { + for (const mutex of this.authPromptLocks.values()) { + mutex.release(); + } + + for (const mutex of this.profileLocks.values()) { + mutex.release(); + } + } + /** * Checks whether the given profile has its lock acquired. * @param profile The profile to check diff --git a/packages/zowe-explorer/src/trees/shared/SharedInit.ts b/packages/zowe-explorer/src/trees/shared/SharedInit.ts index a5cae7ae4..40ac59f6e 100644 --- a/packages/zowe-explorer/src/trees/shared/SharedInit.ts +++ b/packages/zowe-explorer/src/trees/shared/SharedInit.ts @@ -22,6 +22,7 @@ import { ZoweScheme, ZoweVsCodeExtension, imperative, + AuthHandler, } from "@zowe/zowe-explorer-api"; import { SharedActions } from "./SharedActions"; import { SharedHistoryView } from "./SharedHistoryView"; @@ -367,6 +368,7 @@ export class SharedInit { try { const zoweWatcher = imperative.EventOperator.getWatcher().subscribeUser(imperative.ZoweUserEvents.ON_VAULT_CHANGED, async () => { ZoweLogger.info(vscode.l10n.t("Changes in the credential vault detected, refreshing Zowe Explorer.")); + AuthHandler.unlockAllProfiles(); await ProfilesUtils.readConfigFromDisk(); await SharedActions.refreshAll(); ZoweExplorerApiRegister.getInstance().onVaultUpdateEmitter.fire(Validation.EventType.UPDATE);