Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/authentication/browser/actions/manageAccountsAction.ts
4780 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Lazy } from '../../../../../base/common/lazy.js';
7
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
8
import { localize, localize2 } from '../../../../../nls.js';
9
import { Action2 } from '../../../../../platform/actions/common/actions.js';
10
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
11
import { IInstantiationService, ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
12
import { IProductService } from '../../../../../platform/product/common/productService.js';
13
import { IQuickInputService, IQuickPickItem } from '../../../../../platform/quickinput/common/quickInput.js';
14
import { ISecretStorageService } from '../../../../../platform/secrets/common/secrets.js';
15
import { AuthenticationSessionInfo, getCurrentAuthenticationSessionInfo } from '../../../../services/authentication/browser/authenticationService.js';
16
import { IAuthenticationProvider, IAuthenticationService } from '../../../../services/authentication/common/authentication.js';
17
18
export class ManageAccountsAction extends Action2 {
19
constructor() {
20
super({
21
id: 'workbench.action.manageAccounts',
22
title: localize2('manageAccounts', "Manage Accounts"),
23
category: localize2('accounts', "Accounts"),
24
f1: true
25
});
26
}
27
28
public override run(accessor: ServicesAccessor): Promise<void> {
29
const instantiationService = accessor.get(IInstantiationService);
30
return instantiationService.createInstance(ManageAccountsActionImpl).run();
31
}
32
}
33
34
interface AccountQuickPickItem extends IQuickPickItem {
35
providerId: string;
36
canUseMcp: boolean;
37
canSignOut: () => Promise<boolean>;
38
}
39
40
interface AccountActionQuickPickItem extends IQuickPickItem {
41
action: () => void;
42
}
43
44
class ManageAccountsActionImpl {
45
constructor(
46
@IQuickInputService private readonly quickInputService: IQuickInputService,
47
@IAuthenticationService private readonly authenticationService: IAuthenticationService,
48
@ICommandService private readonly commandService: ICommandService,
49
@ISecretStorageService private readonly secretStorageService: ISecretStorageService,
50
@IProductService private readonly productService: IProductService,
51
) { }
52
53
public async run() {
54
const placeHolder = localize('pickAccount', "Select an account to manage");
55
56
const accounts = await this.listAccounts();
57
if (!accounts.length) {
58
await this.quickInputService.pick([{ label: localize('noActiveAccounts', "There are no active accounts.") }], { placeHolder });
59
return;
60
}
61
62
const account = await this.quickInputService.pick(accounts, { placeHolder, matchOnDescription: true });
63
if (!account) {
64
return;
65
}
66
67
await this.showAccountActions(account);
68
}
69
70
private async listAccounts(): Promise<AccountQuickPickItem[]> {
71
const activeSession = new Lazy(() => getCurrentAuthenticationSessionInfo(this.secretStorageService, this.productService));
72
const accounts: AccountQuickPickItem[] = [];
73
for (const providerId of this.authenticationService.getProviderIds()) {
74
const provider = this.authenticationService.getProvider(providerId);
75
for (const { label, id } of await this.authenticationService.getAccounts(providerId)) {
76
accounts.push({
77
label,
78
description: provider.label,
79
providerId,
80
canUseMcp: !!provider.authorizationServers?.length,
81
canSignOut: async () => this.canSignOut(provider, id, await activeSession.value)
82
});
83
}
84
}
85
return accounts;
86
}
87
88
private async canSignOut(provider: IAuthenticationProvider, accountId: string, session?: AuthenticationSessionInfo): Promise<boolean> {
89
if (session && !session.canSignOut && session.providerId === provider.id) {
90
const sessions = await this.authenticationService.getSessions(provider.id);
91
return !sessions.some(o => o.id === session.id && o.account.id === accountId);
92
}
93
return true;
94
}
95
96
private async showAccountActions(account: AccountQuickPickItem): Promise<void> {
97
const { providerId, label: accountLabel, canUseMcp, canSignOut } = account;
98
99
const store = new DisposableStore();
100
const quickPick = store.add(this.quickInputService.createQuickPick<AccountActionQuickPickItem>());
101
102
quickPick.title = localize('manageAccount', "Manage '{0}'", accountLabel);
103
quickPick.placeholder = localize('selectAction', "Select an action");
104
quickPick.buttons = [this.quickInputService.backButton];
105
106
const items: AccountActionQuickPickItem[] = [{
107
label: localize('manageTrustedExtensions', "Manage Trusted Extensions"),
108
action: () => this.commandService.executeCommand('_manageTrustedExtensionsForAccount', { providerId, accountLabel })
109
}];
110
111
if (canUseMcp) {
112
items.push({
113
label: localize('manageTrustedMCPServers', "Manage Trusted MCP Servers"),
114
action: () => this.commandService.executeCommand('_manageTrustedMCPServersForAccount', { providerId, accountLabel })
115
});
116
}
117
118
if (await canSignOut()) {
119
items.push({
120
label: localize('signOut', "Sign Out"),
121
action: () => this.commandService.executeCommand('_signOutOfAccount', { providerId, accountLabel })
122
});
123
}
124
125
quickPick.items = items;
126
127
store.add(quickPick.onDidAccept(() => {
128
const selected = quickPick.selectedItems[0];
129
if (selected) {
130
quickPick.hide();
131
selected.action();
132
}
133
}));
134
135
store.add(quickPick.onDidTriggerButton((button) => {
136
if (button === this.quickInputService.backButton) {
137
void this.run();
138
}
139
}));
140
141
store.add(quickPick.onDidHide(() => store.dispose()));
142
143
quickPick.show();
144
}
145
}
146
147