Skip to content

Commit bb24a31

Browse files
committed
Implement migration and deletion
1 parent 2091267 commit bb24a31

File tree

1 file changed

+44
-23
lines changed

1 file changed

+44
-23
lines changed

src/commands/managePasswords.ts

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,23 @@ export async function clearPassword(treeItem?: ServerTreeItem): Promise<string>
6161
return reply;
6262
}
6363

64+
interface IMigratePasswordItem extends vscode.QuickPickItem {
65+
serverName: string;
66+
userName: string;
67+
password: string;
68+
};
69+
6470
export async function migratePasswords(secretStorage: vscode.SecretStorage): Promise<void> {
6571
const credentials = await Keychain.findCredentials();
66-
console.log(credentials);
6772
if (credentials.length === 0) {
68-
vscode.window.showInformationMessage('No legacy passwords found');
73+
vscode.window.showInformationMessage('No legacy stored passwords found.');
6974
} else {
7075

7176
// Collect only those for which server definition exists with a username
7277
// and no credentials yet stored in our SecretStorage
73-
const migratableCredentials = (await Promise.all(
74-
credentials.map(async (item) => {
78+
const migratableCredentials: IMigratePasswordItem[] = [];
79+
(await Promise.all(
80+
credentials.map(async (item): Promise<IMigratePasswordItem | undefined> => {
7581
const serverName = item.account;
7682
const username: string | undefined = vscode.workspace.getConfiguration("intersystems.servers." + serverName).get("username");
7783
if (!username) {
@@ -82,33 +88,48 @@ export async function migratePasswords(secretStorage: vscode.SecretStorage): Pro
8288
}
8389
const sessionId = ServerManagerAuthenticationProvider.sessionId(serverName, username);
8490
const credentialKey = ServerManagerAuthenticationProvider.credentialKey(sessionId);
85-
return (await secretStorage.get(credentialKey) ? {...item, username} : undefined);
91+
return (await secretStorage.get(credentialKey) ? undefined : {label: `${serverName} (${username})`, picked: true, serverName, userName: username, password: item.password});
8692
})
8793
))
88-
.filter((item) => item);
94+
.forEach((item) => {
95+
if (item) {
96+
migratableCredentials.push(item);
97+
}
98+
});
8999
if (migratableCredentials.length === 0) {
90-
vscode.window.showInformationMessage('No legacy passwords found for servers whose definitions specify a username');
100+
const message = 'No remaining legacy stored passwords are eligible for migration.';
101+
const detail = 'They are either for servers with a password already stored in the new format, or for servers whose definition does not specify a username.'
102+
await vscode.window.showWarningMessage(message,
103+
{modal: true, detail},
104+
//{title: "OK", isCloseAffordance: true}
105+
);
91106
} else {
92-
const disqualified = credentials.length - migratableCredentials.length;
93-
const detail = disqualified > 0 ? `${disqualified} other ${disqualified > 1 ? "passwords" : "password"} ignored because associated server is no longer defined, or has no username set, or already has a password in the new keystore.` : "";
94-
const message = `Migrate ${migratableCredentials.length} legacy stored ${migratableCredentials.length > 1 ? "passwords" : "password"}?`;
95-
switch (await vscode.window.showInformationMessage(message, {modal: true, detail}, "Yes", "No")) {
96-
case undefined:
97-
return;
98-
99-
case "Yes":
100-
vscode.window.showInformationMessage('TODO migration');
101-
break;
102-
103-
default:
104-
break;
107+
const choices = await vscode.window.showQuickPick<IMigratePasswordItem>(migratableCredentials,
108+
{ canPickMany: true,
109+
title: "Migrate Server Manager legacy stored passwords",
110+
placeHolder: "Select connections whose passwords you want to migrate"
111+
}
112+
)
113+
if (!choices) {
114+
return;
115+
} else if (choices.length > 0) {
116+
await Promise.all(choices.map(async (item) => {
117+
const sessionId = ServerManagerAuthenticationProvider.sessionId(item.serverName, item.userName);
118+
const credentialKey = ServerManagerAuthenticationProvider.credentialKey(sessionId);
119+
return secretStorage.store(credentialKey, item.password);
120+
}));
121+
vscode.window.showInformationMessage(`Migrated ${choices.length} ${choices.length > 1 ? "passwords" : "password"}.`);
105122
}
106123
}
107124
const detail = "Do this to tidy up your keystore once you have migrated passwords and will not be reverting to an earlier Server Manager.";
108-
if (await vscode.window.showInformationMessage(`Delete all legacy stored passwords?`, {modal: true, detail}, "Yes", "No") === "Yes") {
109-
vscode.window.showInformationMessage('TODO deletion');
125+
if ((await vscode.window.showInformationMessage(`Delete all legacy stored passwords?`, {modal: true, detail}, {title: "Yes"}, {title: "No", isCloseAffordance: true}))?.title === "Yes") {
126+
await Promise.all(credentials.map(async (item) => {
127+
const keychain = new Keychain(item.account);
128+
return keychain.deletePassword()
129+
}));
130+
vscode.window.showInformationMessage(`Deleted ${credentials.length} ${credentials.length > 1 ? "passwords" : "password"}.`);
110131
}
111-
}
132+
}
112133
return;
113134
}
114135

0 commit comments

Comments
 (0)