@codingame/monaco-vscode-authentication-service-override 18.3.1 → 19.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/index.js +5 -1
  2. package/package.json +5 -4
  3. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageAccountPreferencesForExtensionAction.d.ts +6 -0
  4. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageAccountPreferencesForExtensionAction.js +171 -0
  5. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageAccountPreferencesForMcpServerAction.d.ts +6 -0
  6. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageAccountPreferencesForMcpServerAction.js +171 -0
  7. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageDynamicAuthenticationProvidersAction.d.ts +7 -0
  8. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageDynamicAuthenticationProvidersAction.js +76 -0
  9. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageTrustedExtensionsForAccountAction.d.ts +9 -0
  10. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageTrustedExtensionsForAccountAction.js +177 -0
  11. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageTrustedMcpServersForAccountAction.d.ts +9 -0
  12. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/manageTrustedMcpServersForAccountAction.js +171 -0
  13. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/signOutOfAccountAction.d.ts +9 -0
  14. package/vscode/src/vs/workbench/contrib/authentication/browser/actions/signOutOfAccountAction.js +52 -0
  15. package/vscode/src/vs/workbench/contrib/authentication/browser/authentication.contribution.d.ts +1 -0
  16. package/vscode/src/vs/workbench/contrib/authentication/browser/authentication.contribution.js +140 -0
  17. package/vscode/src/vs/workbench/services/authentication/browser/authenticationAccessService.js +39 -6
  18. package/vscode/src/vs/workbench/services/authentication/browser/authenticationExtensionsService.js +9 -9
  19. package/vscode/src/vs/workbench/services/authentication/browser/authenticationQueryService.d.ts +39 -0
  20. package/vscode/src/vs/workbench/services/authentication/browser/authenticationQueryService.js +613 -0
  21. package/vscode/src/vs/workbench/services/authentication/browser/authenticationUsageService.d.ts +1 -0
  22. package/vscode/src/vs/workbench/services/authentication/browser/authenticationUsageService.js +7 -2
@@ -0,0 +1,177 @@
1
+
2
+ import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
+ import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codicons';
4
+ import { fromNow } from '@codingame/monaco-vscode-api/vscode/vs/base/common/date';
5
+ import { DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
6
+ import { ThemeIcon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/themables';
7
+ import { localize2, localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
8
+ import { Action2 } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions';
9
+ import { ICommandService } from '@codingame/monaco-vscode-api/vscode/vs/platform/commands/common/commands.service';
10
+ import { IDialogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service';
11
+ import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
12
+ import { IQuickInputService } from '@codingame/monaco-vscode-api/vscode/vs/platform/quickinput/common/quickInput.service';
13
+ import { IAuthenticationService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/common/authentication.service';
14
+ import { IAuthenticationQueryService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/common/authenticationQuery.service';
15
+ import { IExtensionService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/extensions/common/extensions.service';
16
+
17
+ class ManageTrustedExtensionsForAccountAction extends Action2 {
18
+ constructor() {
19
+ super({
20
+ id: '_manageTrustedExtensionsForAccount',
21
+ title: ( localize2(4310, "Manage Trusted Extensions For Account")),
22
+ category: ( localize2(4311, "Accounts")),
23
+ f1: true
24
+ });
25
+ }
26
+ run(accessor, options) {
27
+ const instantiationService = accessor.get(IInstantiationService);
28
+ return instantiationService.createInstance(ManageTrustedExtensionsForAccountActionImpl).run(options);
29
+ }
30
+ }
31
+ let ManageTrustedExtensionsForAccountActionImpl = class ManageTrustedExtensionsForAccountActionImpl {
32
+ constructor(_extensionService, _dialogService, _quickInputService, _authenticationService, _authenticationQueryService, _commandService) {
33
+ this._extensionService = _extensionService;
34
+ this._dialogService = _dialogService;
35
+ this._quickInputService = _quickInputService;
36
+ this._authenticationService = _authenticationService;
37
+ this._authenticationQueryService = _authenticationQueryService;
38
+ this._commandService = _commandService;
39
+ }
40
+ async run(options) {
41
+ const accountQuery = await this._resolveAccountQuery(options?.providerId, options?.accountLabel);
42
+ if (!accountQuery) {
43
+ return;
44
+ }
45
+ const items = await this._getItems(accountQuery);
46
+ if (!items.length) {
47
+ return;
48
+ }
49
+ const picker = this._createQuickPick(accountQuery);
50
+ picker.items = items;
51
+ picker.selectedItems = items.filter((i) => i.type !== 'separator' && !!i.picked);
52
+ picker.show();
53
+ }
54
+ async _resolveAccountQuery(providerId, accountLabel) {
55
+ if (providerId && accountLabel) {
56
+ return this._authenticationQueryService.provider(providerId).account(accountLabel);
57
+ }
58
+ const accounts = await this._getAllAvailableAccounts();
59
+ const pick = await this._quickInputService.pick(accounts, {
60
+ placeHolder: ( localize(4312, "Pick an account to manage trusted extensions for")),
61
+ matchOnDescription: true,
62
+ });
63
+ return pick ? this._authenticationQueryService.provider(pick.providerId).account(pick.label) : undefined;
64
+ }
65
+ async _getAllAvailableAccounts() {
66
+ const accounts = [];
67
+ for (const providerId of this._authenticationService.getProviderIds()) {
68
+ const provider = this._authenticationService.getProvider(providerId);
69
+ const sessions = await this._authenticationService.getSessions(providerId);
70
+ const uniqueLabels = ( new Set());
71
+ for (const session of sessions) {
72
+ if (!( uniqueLabels.has(session.account.label))) {
73
+ uniqueLabels.add(session.account.label);
74
+ accounts.push({
75
+ providerId,
76
+ label: session.account.label,
77
+ description: provider.label
78
+ });
79
+ }
80
+ }
81
+ }
82
+ return accounts;
83
+ }
84
+ async _getItems(accountQuery) {
85
+ const allowedExtensions = accountQuery.extensions().getAllowedExtensions();
86
+ const extensionIdToDisplayName = ( new Map());
87
+ const resolvedExtensions = await Promise.all(( allowedExtensions.map(ext => this._extensionService.getExtension(ext.id))));
88
+ resolvedExtensions.forEach((resolved, i) => {
89
+ if (resolved) {
90
+ extensionIdToDisplayName.set(allowedExtensions[i].id, resolved.displayName || resolved.name);
91
+ }
92
+ });
93
+ const filteredExtensions = ( allowedExtensions
94
+ .filter(ext => ( extensionIdToDisplayName.has(ext.id)))
95
+ .map(ext => {
96
+ const usage = accountQuery.extension(ext.id).getUsage();
97
+ return {
98
+ ...ext,
99
+ name: extensionIdToDisplayName.get(ext.id),
100
+ lastUsed: usage.length > 0 ? Math.max(...( usage.map(u => u.lastUsed))) : ext.lastUsed
101
+ };
102
+ }));
103
+ if (!filteredExtensions.length) {
104
+ this._dialogService.info(( localize(4313, "This account has not been used by any extensions.")));
105
+ return [];
106
+ }
107
+ const trustedExtensions = filteredExtensions.filter(e => e.trusted);
108
+ const otherExtensions = filteredExtensions.filter(e => !e.trusted);
109
+ const sortByLastUsed = (a, b) => (b.lastUsed || 0) - (a.lastUsed || 0);
110
+ return [
111
+ ...( otherExtensions.sort(sortByLastUsed).map(this._toQuickPickItem)),
112
+ { type: 'separator', label: ( localize(4314, "Trusted by Microsoft")) },
113
+ ...( trustedExtensions.sort(sortByLastUsed).map(this._toQuickPickItem))
114
+ ];
115
+ }
116
+ _toQuickPickItem(extension) {
117
+ const lastUsed = extension.lastUsed;
118
+ const description = lastUsed
119
+ ? ( localize(4315, "Last used this account {0}", fromNow(lastUsed, true)))
120
+ : ( localize(4316, "Has not used this account"));
121
+ let tooltip;
122
+ let disabled;
123
+ if (extension.trusted) {
124
+ tooltip = ( localize(
125
+ 4317,
126
+ "This extension is trusted by Microsoft and\nalways has access to this account"
127
+ ));
128
+ disabled = true;
129
+ }
130
+ return {
131
+ label: extension.name,
132
+ extension,
133
+ description,
134
+ tooltip,
135
+ disabled,
136
+ buttons: [{
137
+ tooltip: ( localize(4318, "Manage account preferences for this extension")),
138
+ iconClass: ThemeIcon.asClassName(Codicon.settingsGear),
139
+ }],
140
+ picked: extension.allowed === undefined || extension.allowed
141
+ };
142
+ }
143
+ _createQuickPick(accountQuery) {
144
+ const disposableStore = ( new DisposableStore());
145
+ const quickPick = disposableStore.add(this._quickInputService.createQuickPick({ useSeparators: true }));
146
+ quickPick.canSelectMany = true;
147
+ quickPick.customButton = true;
148
+ quickPick.customLabel = ( localize(4319, 'Cancel'));
149
+ quickPick.title = ( localize(4320, "Manage Trusted Extensions"));
150
+ quickPick.placeholder = ( localize(4321, "Choose which extensions can access this account"));
151
+ disposableStore.add(quickPick.onDidAccept(() => {
152
+ const updatedAllowedList = ( quickPick.items
153
+ .filter((item) => item.type !== 'separator')
154
+ .map(i => i.extension));
155
+ const allowedExtensionsSet = ( new Set(( quickPick.selectedItems.map(i => i.extension))));
156
+ for (const extension of updatedAllowedList) {
157
+ const allowed = ( allowedExtensionsSet.has(extension));
158
+ accountQuery.extension(extension.id).setAccessAllowed(allowed, extension.name);
159
+ }
160
+ quickPick.hide();
161
+ }));
162
+ disposableStore.add(quickPick.onDidHide(() => disposableStore.dispose()));
163
+ disposableStore.add(quickPick.onDidCustom(() => quickPick.hide()));
164
+ disposableStore.add(quickPick.onDidTriggerItemButton(e => this._commandService.executeCommand('_manageAccountPreferencesForExtension', e.item.extension.id, accountQuery.providerId)));
165
+ return quickPick;
166
+ }
167
+ };
168
+ ManageTrustedExtensionsForAccountActionImpl = ( __decorate([
169
+ ( __param(0, IExtensionService)),
170
+ ( __param(1, IDialogService)),
171
+ ( __param(2, IQuickInputService)),
172
+ ( __param(3, IAuthenticationService)),
173
+ ( __param(4, IAuthenticationQueryService)),
174
+ ( __param(5, ICommandService))
175
+ ], ManageTrustedExtensionsForAccountActionImpl));
176
+
177
+ export { ManageTrustedExtensionsForAccountAction };
@@ -0,0 +1,9 @@
1
+ import { Action2 } from "@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions";
2
+ import { ServicesAccessor } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
3
+ export declare class ManageTrustedMcpServersForAccountAction extends Action2 {
4
+ constructor();
5
+ run(accessor: ServicesAccessor, options?: {
6
+ providerId: string;
7
+ accountLabel: string;
8
+ }): Promise<void>;
9
+ }
@@ -0,0 +1,171 @@
1
+
2
+ import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
+ import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codicons';
4
+ import { fromNow } from '@codingame/monaco-vscode-api/vscode/vs/base/common/date';
5
+ import { DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
6
+ import { ThemeIcon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/themables';
7
+ import { localize2, localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
8
+ import { Action2 } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions';
9
+ import { ICommandService } from '@codingame/monaco-vscode-api/vscode/vs/platform/commands/common/commands.service';
10
+ import { IDialogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service';
11
+ import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
12
+ import { IQuickInputService } from '@codingame/monaco-vscode-api/vscode/vs/platform/quickinput/common/quickInput.service';
13
+ import { IAuthenticationService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/common/authentication.service';
14
+ import { IAuthenticationQueryService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/common/authenticationQuery.service';
15
+ import { IMcpService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes.service';
16
+
17
+ class ManageTrustedMcpServersForAccountAction extends Action2 {
18
+ constructor() {
19
+ super({
20
+ id: '_manageTrustedMCPServersForAccount',
21
+ title: ( localize2(4322, "Manage Trusted MCP Servers For Account")),
22
+ category: ( localize2(4323, "Accounts")),
23
+ f1: true
24
+ });
25
+ }
26
+ run(accessor, options) {
27
+ const instantiationService = accessor.get(IInstantiationService);
28
+ return instantiationService.createInstance(ManageTrustedMcpServersForAccountActionImpl).run(options);
29
+ }
30
+ }
31
+ let ManageTrustedMcpServersForAccountActionImpl = class ManageTrustedMcpServersForAccountActionImpl {
32
+ constructor(_mcpServerService, _dialogService, _quickInputService, _mcpServerAuthenticationService, _authenticationQueryService, _commandService) {
33
+ this._mcpServerService = _mcpServerService;
34
+ this._dialogService = _dialogService;
35
+ this._quickInputService = _quickInputService;
36
+ this._mcpServerAuthenticationService = _mcpServerAuthenticationService;
37
+ this._authenticationQueryService = _authenticationQueryService;
38
+ this._commandService = _commandService;
39
+ }
40
+ async run(options) {
41
+ const accountQuery = await this._resolveAccountQuery(options?.providerId, options?.accountLabel);
42
+ if (!accountQuery) {
43
+ return;
44
+ }
45
+ const items = await this._getItems(accountQuery);
46
+ if (!items.length) {
47
+ return;
48
+ }
49
+ const picker = this._createQuickPick(accountQuery);
50
+ picker.items = items;
51
+ picker.selectedItems = items.filter((i) => i.type !== 'separator' && !!i.picked);
52
+ picker.show();
53
+ }
54
+ async _resolveAccountQuery(providerId, accountLabel) {
55
+ if (providerId && accountLabel) {
56
+ return this._authenticationQueryService.provider(providerId).account(accountLabel);
57
+ }
58
+ const accounts = await this._getAllAvailableAccounts();
59
+ const pick = await this._quickInputService.pick(accounts, {
60
+ placeHolder: ( localize(4324, "Pick an account to manage trusted MCP servers for")),
61
+ matchOnDescription: true,
62
+ });
63
+ return pick ? this._authenticationQueryService.provider(pick.providerId).account(pick.label) : undefined;
64
+ }
65
+ async _getAllAvailableAccounts() {
66
+ const accounts = [];
67
+ for (const providerId of this._mcpServerAuthenticationService.getProviderIds()) {
68
+ const provider = this._mcpServerAuthenticationService.getProvider(providerId);
69
+ const sessions = await this._mcpServerAuthenticationService.getSessions(providerId);
70
+ const uniqueLabels = ( new Set());
71
+ for (const session of sessions) {
72
+ if (!( uniqueLabels.has(session.account.label))) {
73
+ uniqueLabels.add(session.account.label);
74
+ accounts.push({
75
+ providerId,
76
+ label: session.account.label,
77
+ description: provider.label
78
+ });
79
+ }
80
+ }
81
+ }
82
+ return accounts;
83
+ }
84
+ async _getItems(accountQuery) {
85
+ const allowedMcpServers = accountQuery.mcpServers().getAllowedMcpServers();
86
+ const serverIdToLabel = ( new Map(( this._mcpServerService.servers.get().map(s => [s.definition.id, s.definition.label]))));
87
+ const filteredMcpServers = ( allowedMcpServers
88
+ .filter(server => ( serverIdToLabel.has(server.id)))
89
+ .map(server => {
90
+ const usage = accountQuery.mcpServer(server.id).getUsage();
91
+ return {
92
+ ...server,
93
+ name: serverIdToLabel.get(server.id),
94
+ lastUsed: usage.length > 0 ? Math.max(...( usage.map(u => u.lastUsed))) : server.lastUsed
95
+ };
96
+ }));
97
+ if (!filteredMcpServers.length) {
98
+ this._dialogService.info(( localize(4325, "This account has not been used by any MCP servers.")));
99
+ return [];
100
+ }
101
+ const trustedServers = filteredMcpServers.filter(s => s.trusted);
102
+ const otherServers = filteredMcpServers.filter(s => !s.trusted);
103
+ const sortByLastUsed = (a, b) => (b.lastUsed || 0) - (a.lastUsed || 0);
104
+ return [
105
+ ...( otherServers.sort(sortByLastUsed).map(this._toQuickPickItem)),
106
+ { type: 'separator', label: ( localize(4326, "Trusted by Microsoft")) },
107
+ ...( trustedServers.sort(sortByLastUsed).map(this._toQuickPickItem))
108
+ ];
109
+ }
110
+ _toQuickPickItem(mcpServer) {
111
+ const lastUsed = mcpServer.lastUsed;
112
+ const description = lastUsed
113
+ ? ( localize(4327, "Last used this account {0}", fromNow(lastUsed, true)))
114
+ : ( localize(4328, "Has not used this account"));
115
+ let tooltip;
116
+ let disabled;
117
+ if (mcpServer.trusted) {
118
+ tooltip = ( localize(
119
+ 4329,
120
+ "This MCP server is trusted by Microsoft and\nalways has access to this account"
121
+ ));
122
+ disabled = true;
123
+ }
124
+ return {
125
+ label: mcpServer.name,
126
+ mcpServer,
127
+ description,
128
+ tooltip,
129
+ disabled,
130
+ buttons: [{
131
+ tooltip: ( localize(4330, "Manage account preferences for this MCP server")),
132
+ iconClass: ThemeIcon.asClassName(Codicon.settingsGear),
133
+ }],
134
+ picked: mcpServer.allowed === undefined || mcpServer.allowed
135
+ };
136
+ }
137
+ _createQuickPick(accountQuery) {
138
+ const disposableStore = ( new DisposableStore());
139
+ const quickPick = disposableStore.add(this._quickInputService.createQuickPick({ useSeparators: true }));
140
+ quickPick.canSelectMany = true;
141
+ quickPick.customButton = true;
142
+ quickPick.customLabel = ( localize(4331, 'Cancel'));
143
+ quickPick.title = ( localize(4332, "Manage Trusted MCP Servers"));
144
+ quickPick.placeholder = ( localize(4333, "Choose which MCP servers can access this account"));
145
+ disposableStore.add(quickPick.onDidAccept(() => {
146
+ quickPick.hide();
147
+ const allServers = ( quickPick.items
148
+ .filter((item) => item.type !== 'separator')
149
+ .map((i) => i.mcpServer));
150
+ const selectedServers = ( new Set(( quickPick.selectedItems.map((i) => i.mcpServer))));
151
+ for (const mcpServer of allServers) {
152
+ const isAllowed = ( selectedServers.has(mcpServer));
153
+ accountQuery.mcpServer(mcpServer.id).setAccessAllowed(isAllowed, mcpServer.name);
154
+ }
155
+ }));
156
+ disposableStore.add(quickPick.onDidHide(() => disposableStore.dispose()));
157
+ disposableStore.add(quickPick.onDidCustom(() => quickPick.hide()));
158
+ disposableStore.add(quickPick.onDidTriggerItemButton((e) => this._commandService.executeCommand('_manageAccountPreferencesForMcpServer', e.item.mcpServer.id, accountQuery.providerId)));
159
+ return quickPick;
160
+ }
161
+ };
162
+ ManageTrustedMcpServersForAccountActionImpl = ( __decorate([
163
+ ( __param(0, IMcpService)),
164
+ ( __param(1, IDialogService)),
165
+ ( __param(2, IQuickInputService)),
166
+ ( __param(3, IAuthenticationService)),
167
+ ( __param(4, IAuthenticationQueryService)),
168
+ ( __param(5, ICommandService))
169
+ ], ManageTrustedMcpServersForAccountActionImpl));
170
+
171
+ export { ManageTrustedMcpServersForAccountAction };
@@ -0,0 +1,9 @@
1
+ import { Action2 } from "@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions";
2
+ import { ServicesAccessor } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
3
+ export declare class SignOutOfAccountAction extends Action2 {
4
+ constructor();
5
+ run(accessor: ServicesAccessor, { providerId, accountLabel }: {
6
+ providerId: string;
7
+ accountLabel: string;
8
+ }): Promise<void>;
9
+ }
@@ -0,0 +1,52 @@
1
+
2
+ import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity';
3
+ import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
4
+ import { Action2 } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions';
5
+ import { IDialogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service';
6
+ import { IAuthenticationAccessService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/browser/authenticationAccessService.service';
7
+ import { IAuthenticationUsageService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/browser/authenticationUsageService.service';
8
+ import { IAuthenticationService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/common/authentication.service';
9
+
10
+ class SignOutOfAccountAction extends Action2 {
11
+ constructor() {
12
+ super({
13
+ id: '_signOutOfAccount',
14
+ title: ( localize(4334, "Sign out of account")),
15
+ f1: false
16
+ });
17
+ }
18
+ async run(accessor, { providerId, accountLabel }) {
19
+ const authenticationService = accessor.get(IAuthenticationService);
20
+ const authenticationUsageService = accessor.get(IAuthenticationUsageService);
21
+ const authenticationAccessService = accessor.get(IAuthenticationAccessService);
22
+ const dialogService = accessor.get(IDialogService);
23
+ if (!providerId || !accountLabel) {
24
+ throw ( new Error(
25
+ 'Invalid arguments. Expected: { providerId: string; accountLabel: string }'
26
+ ));
27
+ }
28
+ const allSessions = await authenticationService.getSessions(providerId);
29
+ const sessions = allSessions.filter(s => s.account.label === accountLabel);
30
+ const accountUsages = authenticationUsageService.readAccountUsages(providerId, accountLabel);
31
+ const { confirmed } = await dialogService.confirm({
32
+ type: Severity.Info,
33
+ message: accountUsages.length
34
+ ? ( localize(
35
+ 4335,
36
+ "The account '{0}' has been used by: \n\n{1}\n\n Sign out from these extensions?",
37
+ accountLabel,
38
+ ( accountUsages.map(usage => usage.extensionName)).join('\n')
39
+ ))
40
+ : ( localize(4336, "Sign out of '{0}'?", accountLabel)),
41
+ primaryButton: ( localize(4337, "&&Sign Out"))
42
+ });
43
+ if (confirmed) {
44
+ const removeSessionPromises = ( sessions.map(session => authenticationService.removeSession(providerId, session.id)));
45
+ await Promise.all(removeSessionPromises);
46
+ authenticationUsageService.removeAccountUsage(providerId, accountLabel);
47
+ authenticationAccessService.removeAllowedExtensions(providerId, accountLabel);
48
+ }
49
+ }
50
+ }
51
+
52
+ export { SignOutOfAccountAction };
@@ -0,0 +1,140 @@
1
+
2
+ import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
+ import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
4
+ import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
5
+ import { registerAction2 } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions';
6
+ import { CommandsRegistry } from '@codingame/monaco-vscode-api/vscode/vs/platform/commands/common/commands';
7
+ import { SyncDescriptor } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/descriptors';
8
+ import { Registry } from '@codingame/monaco-vscode-api/vscode/vs/platform/registry/common/platform';
9
+ import { registerWorkbenchContribution2, WorkbenchPhase } from '@codingame/monaco-vscode-api/vscode/vs/workbench/common/contributions';
10
+ import { SignOutOfAccountAction } from './actions/signOutOfAccountAction.js';
11
+ import { IBrowserWorkbenchEnvironmentService } from '@codingame/monaco-vscode-34a0ffd3-b9f5-5699-b43b-38af5732f38a-common/vscode/vs/workbench/services/environment/browser/environmentService.service';
12
+ import { Extensions } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/extensionManagement/common/extensionFeatures';
13
+ import { ManageTrustedExtensionsForAccountAction } from './actions/manageTrustedExtensionsForAccountAction.js';
14
+ import { ManageAccountPreferencesForExtensionAction } from './actions/manageAccountPreferencesForExtensionAction.js';
15
+ import { IAuthenticationUsageService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/browser/authenticationUsageService.service';
16
+ import { ManageAccountPreferencesForMcpServerAction } from './actions/manageAccountPreferencesForMcpServerAction.js';
17
+ import { ManageTrustedMcpServersForAccountAction } from './actions/manageTrustedMcpServersForAccountAction.js';
18
+ import { RemoveDynamicAuthenticationProvidersAction } from './actions/manageDynamicAuthenticationProvidersAction.js';
19
+ import { IAuthenticationQueryService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/common/authenticationQuery.service';
20
+ import { IMcpRegistry } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpRegistryTypes.service';
21
+ import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
22
+ import { IAuthenticationService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/common/authentication.service';
23
+ import { Event } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
24
+ import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
25
+
26
+ const codeExchangeProxyCommand = CommandsRegistry.registerCommand('workbench.getCodeExchangeProxyEndpoints', function (accessor, _) {
27
+ const environmentService = accessor.get(IBrowserWorkbenchEnvironmentService);
28
+ return environmentService.options?.codeExchangeProxyEndpoints;
29
+ });
30
+ class AuthenticationDataRenderer extends Disposable {
31
+ constructor() {
32
+ super(...arguments);
33
+ this.type = 'table';
34
+ }
35
+ shouldRender(manifest) {
36
+ return !!manifest.contributes?.authentication;
37
+ }
38
+ render(manifest) {
39
+ const authentication = manifest.contributes?.authentication || [];
40
+ if (!authentication.length) {
41
+ return { data: { headers: [], rows: [] }, dispose: () => { } };
42
+ }
43
+ const headers = [
44
+ ( localize(4338, "Label")),
45
+ ( localize(4339, "ID")),
46
+ ( localize(4340, "MCP Authorization Servers"))
47
+ ];
48
+ const rows = ( authentication
49
+ .sort((a, b) => a.label.localeCompare(b.label))
50
+ .map(auth => {
51
+ return [
52
+ auth.label,
53
+ auth.id,
54
+ (auth.authorizationServerGlobs ?? []).join(',\n')
55
+ ];
56
+ }));
57
+ return {
58
+ data: {
59
+ headers,
60
+ rows
61
+ },
62
+ dispose: () => { }
63
+ };
64
+ }
65
+ }
66
+ const extensionFeature = ( Registry.as(Extensions.ExtensionFeaturesRegistry)).registerExtensionFeature({
67
+ id: 'authentication',
68
+ label: ( localize(4341, "Authentication")),
69
+ access: {
70
+ canToggle: false
71
+ },
72
+ renderer: ( new SyncDescriptor(AuthenticationDataRenderer)),
73
+ });
74
+ class AuthenticationContribution extends Disposable {
75
+ static { this.ID = 'workbench.contrib.authentication'; }
76
+ constructor() {
77
+ super();
78
+ this._register(codeExchangeProxyCommand);
79
+ this._register(extensionFeature);
80
+ this._registerActions();
81
+ }
82
+ _registerActions() {
83
+ this._register(registerAction2(SignOutOfAccountAction));
84
+ this._register(registerAction2(ManageTrustedExtensionsForAccountAction));
85
+ this._register(registerAction2(ManageAccountPreferencesForExtensionAction));
86
+ this._register(registerAction2(ManageTrustedMcpServersForAccountAction));
87
+ this._register(registerAction2(ManageAccountPreferencesForMcpServerAction));
88
+ this._register(registerAction2(RemoveDynamicAuthenticationProvidersAction));
89
+ }
90
+ }
91
+ let AuthenticationUsageContribution = class AuthenticationUsageContribution {
92
+ static { this.ID = 'workbench.contrib.authenticationUsage'; }
93
+ constructor(_authenticationUsageService) {
94
+ this._authenticationUsageService = _authenticationUsageService;
95
+ this._initializeExtensionUsageCache();
96
+ }
97
+ async _initializeExtensionUsageCache() {
98
+ await this._authenticationUsageService.initializeExtensionUsageCache();
99
+ }
100
+ };
101
+ AuthenticationUsageContribution = ( __decorate([
102
+ ( __param(0, IAuthenticationUsageService))
103
+ ], AuthenticationUsageContribution));
104
+ let AuthenticationMcpContribution = class AuthenticationMcpContribution extends Disposable {
105
+ static { this.ID = 'workbench.contrib.authenticationMcp'; }
106
+ constructor(_mcpRegistry, _authenticationQueryService, _authenticationService) {
107
+ super();
108
+ this._mcpRegistry = _mcpRegistry;
109
+ this._authenticationQueryService = _authenticationQueryService;
110
+ this._authenticationService = _authenticationService;
111
+ this._cleanupRemovedMcpServers();
112
+ this._register(autorun(reader => {
113
+ this._mcpRegistry.collections.read(reader);
114
+ queueMicrotask(() => this._cleanupRemovedMcpServers());
115
+ }));
116
+ this._register(Event.any(this._authenticationService.onDidChangeDeclaredProviders, this._authenticationService.onDidRegisterAuthenticationProvider)(() => this._cleanupRemovedMcpServers()));
117
+ }
118
+ _cleanupRemovedMcpServers() {
119
+ const currentServerIds = ( new Set(( this._mcpRegistry.collections.get().flatMap(c => c.serverDefinitions.get()).map(s => s.id))));
120
+ const providerIds = this._authenticationQueryService.getProviderIds();
121
+ for (const providerId of providerIds) {
122
+ this._authenticationQueryService.provider(providerId).forEachAccount(account => {
123
+ account.mcpServers().forEach(server => {
124
+ if (!( currentServerIds.has(server.mcpServerId))) {
125
+ server.removeUsage();
126
+ server.setAccessAllowed(false);
127
+ }
128
+ });
129
+ });
130
+ }
131
+ }
132
+ };
133
+ AuthenticationMcpContribution = ( __decorate([
134
+ ( __param(0, IMcpRegistry)),
135
+ ( __param(1, IAuthenticationQueryService)),
136
+ ( __param(2, IAuthenticationService))
137
+ ], AuthenticationMcpContribution));
138
+ registerWorkbenchContribution2(AuthenticationContribution.ID, AuthenticationContribution, WorkbenchPhase.AfterRestored);
139
+ registerWorkbenchContribution2(AuthenticationUsageContribution.ID, AuthenticationUsageContribution, WorkbenchPhase.Eventually);
140
+ registerWorkbenchContribution2(AuthenticationMcpContribution.ID, AuthenticationMcpContribution, WorkbenchPhase.Eventually);
@@ -2,6 +2,7 @@
2
2
  import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
3
  import { Emitter } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
4
4
  import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
5
+ import { ExtensionIdentifier } from '@codingame/monaco-vscode-api/vscode/vs/platform/extensions/common/extensions';
5
6
  import '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/extensions';
6
7
  import { IProductService } from '@codingame/monaco-vscode-api/vscode/vs/platform/product/common/productService.service';
7
8
  import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
@@ -18,16 +19,17 @@ let AuthenticationAccessService = class AuthenticationAccessService extends Disp
18
19
  }
19
20
  isAccessAllowed(providerId, accountName, extensionId) {
20
21
  const trustedExtensionAuthAccess = this._productService.trustedExtensionAuthAccess;
22
+ const extensionKey = ExtensionIdentifier.toKey(extensionId);
21
23
  if (Array.isArray(trustedExtensionAuthAccess)) {
22
- if (trustedExtensionAuthAccess.includes(extensionId)) {
24
+ if (trustedExtensionAuthAccess.includes(extensionKey)) {
23
25
  return true;
24
26
  }
25
27
  }
26
- else if (trustedExtensionAuthAccess?.[providerId]?.includes(extensionId)) {
28
+ else if (trustedExtensionAuthAccess?.[providerId]?.includes(extensionKey)) {
27
29
  return true;
28
30
  }
29
31
  const allowList = this.readAllowedExtensions(providerId, accountName);
30
- const extensionData = allowList.find(extension => extension.id === extensionId);
32
+ const extensionData = allowList.find(extension => extension.id === extensionKey);
31
33
  if (!extensionData) {
32
34
  return undefined;
33
35
  }
@@ -44,20 +46,51 @@ let AuthenticationAccessService = class AuthenticationAccessService extends Disp
44
46
  }
45
47
  }
46
48
  catch (err) { }
49
+ const trustedExtensionAuthAccess = this._productService.trustedExtensionAuthAccess;
50
+ const trustedExtensionIds =
51
+ Array.isArray(trustedExtensionAuthAccess)
52
+ ? trustedExtensionAuthAccess
53
+ : typeof trustedExtensionAuthAccess === 'object'
54
+ ? trustedExtensionAuthAccess[providerId] ?? []
55
+ : [];
56
+ for (const extensionId of trustedExtensionIds) {
57
+ const extensionKey = ExtensionIdentifier.toKey(extensionId);
58
+ const existingExtension = trustedExtensions.find(extension => extension.id === extensionKey);
59
+ if (!existingExtension) {
60
+ trustedExtensions.push({
61
+ id: extensionKey,
62
+ name: extensionId,
63
+ allowed: true,
64
+ trusted: true
65
+ });
66
+ }
67
+ else {
68
+ existingExtension.allowed = true;
69
+ existingExtension.trusted = true;
70
+ }
71
+ }
47
72
  return trustedExtensions;
48
73
  }
49
74
  updateAllowedExtensions(providerId, accountName, extensions) {
50
75
  const allowList = this.readAllowedExtensions(providerId, accountName);
51
76
  for (const extension of extensions) {
52
- const index = allowList.findIndex(e => e.id === extension.id);
77
+ const extensionKey = ExtensionIdentifier.toKey(extension.id);
78
+ const index = allowList.findIndex(e => e.id === extensionKey);
53
79
  if (index === -1) {
54
- allowList.push(extension);
80
+ allowList.push({
81
+ ...extension,
82
+ id: extensionKey
83
+ });
55
84
  }
56
85
  else {
57
86
  allowList[index].allowed = extension.allowed;
87
+ if (extension.name && extension.name !== extensionKey && allowList[index].name !== extension.name) {
88
+ allowList[index].name = extension.name;
89
+ }
58
90
  }
59
91
  }
60
- this._storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.APPLICATION, StorageTarget.USER);
92
+ const userManagedExtensions = allowList.filter(extension => !extension.trusted);
93
+ this._storageService.store(`${providerId}-${accountName}`, JSON.stringify(userManagedExtensions), StorageScope.APPLICATION, StorageTarget.USER);
61
94
  this._onDidChangeExtensionSessionAccess.fire({ providerId, accountName });
62
95
  }
63
96
  removeAllowedExtensions(providerId, accountName) {