@microsoft/vscode-azext-azureauth 3.0.1 → 3.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## 3.1.0 - 2024-11-26
4
+
5
+ * [#1827](https://github.com/microsoft/vscode-azuretools/pull/1827) Add more comprehensive support for multi-account scenarios
6
+ * [#1815](https://github.com/microsoft/vscode-azuretools/issues/1815) Fix `VSCodeAzureSubscriptionProvider.getSubscriptions()` returning empty
7
+
3
8
  ## 3.0.1 - 2024-11-19
4
9
  * [#1819](https://github.com/microsoft/vscode-azuretools/pull/1819) Add account parameter to `AzureSubscriptionProvider.isSignedIn()` function to fix a multi-account issue [#1809](https://github.com/microsoft/vscode-azuretools/issues/1809)
5
10
  * [#1822](https://github.com/microsoft/vscode-azuretools/pull/1822) Add check in `VSCodeAzureSubscriptionProvider.getTenants()` to fix a multi-account issue [#1809](https://github.com/microsoft/vscode-azuretools/issues/1809)
@@ -39,10 +39,11 @@ export interface AzureSubscriptionProvider {
39
39
  * Asks the user to sign in or pick an account to use.
40
40
  *
41
41
  * @param tenantId (Optional) Provide to sign in to a specific tenant.
42
+ * @param account (Optional) Provide to sign in to a specific account.
42
43
  *
43
44
  * @returns True if the user is signed in, false otherwise.
44
45
  */
45
- signIn(tenantId?: string): Promise<boolean>;
46
+ signIn(tenantId?: string, account?: vscode.AuthenticationSessionAccountInformation): Promise<boolean>;
46
47
  /**
47
48
  * An event that is fired when the user signs in. Debounced to fire at most once every 5 seconds.
48
49
  */
@@ -28,7 +28,8 @@ export declare class VSCodeAzureSubscriptionProvider extends vscode.Disposable i
28
28
  * @param filter - Whether to filter the list returned, according to the list returned
29
29
  * by `getTenantFilters()` and `getSubscriptionFilters()`. Optional, default true.
30
30
  *
31
- * @returns A list of Azure subscriptions.
31
+ * @returns A list of Azure subscriptions. The list is sorted by subscription name.
32
+ * The list can contain duplicate subscriptions if they come from different accounts.
32
33
  *
33
34
  * @throws A {@link NotSignedInError} If the user is not signed in to Azure.
34
35
  * Use {@link isSignedIn} and/or {@link signIn} before this method to ensure
@@ -39,18 +40,23 @@ export declare class VSCodeAzureSubscriptionProvider extends vscode.Disposable i
39
40
  * Checks to see if a user is signed in.
40
41
  *
41
42
  * @param tenantId (Optional) Provide to check if a user is signed in to a specific tenant.
43
+ * @param account (Optional) Provide to check if a user is signed in to a specific account.
42
44
  *
43
45
  * @returns True if the user is signed in, false otherwise.
46
+ *
47
+ * If no tenant or account is provided, then
48
+ * checks all accounts for a session.
44
49
  */
45
50
  isSignedIn(tenantId?: string, account?: vscode.AuthenticationSessionAccountInformation): Promise<boolean>;
46
51
  /**
47
52
  * Asks the user to sign in or pick an account to use.
48
53
  *
49
54
  * @param tenantId (Optional) Provide to sign in to a specific tenant.
55
+ * @param account (Optional) Provide to sign in to a specific account.
50
56
  *
51
57
  * @returns True if the user is signed in, false otherwise.
52
58
  */
53
- signIn(tenantId?: string): Promise<boolean>;
59
+ signIn(tenantId?: string, account?: vscode.AuthenticationSessionAccountInformation): Promise<boolean>;
54
60
  /**
55
61
  * An event that is fired when the user signs in. Debounced to fire at most once every 5 seconds.
56
62
  */
@@ -131,7 +131,8 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
131
131
  * @param filter - Whether to filter the list returned, according to the list returned
132
132
  * by `getTenantFilters()` and `getSubscriptionFilters()`. Optional, default true.
133
133
  *
134
- * @returns A list of Azure subscriptions.
134
+ * @returns A list of Azure subscriptions. The list is sorted by subscription name.
135
+ * The list can contain duplicate subscriptions if they come from different accounts.
135
136
  *
136
137
  * @throws A {@link NotSignedInError} If the user is not signed in to Azure.
137
138
  * Use {@link isSignedIn} and/or {@link signIn} before this method to ensure
@@ -141,7 +142,7 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
141
142
  return __awaiter(this, void 0, void 0, function* () {
142
143
  const tenantIds = yield this.getTenantFilters();
143
144
  const shouldFilterTenants = filter && !!tenantIds.length; // If the list is empty it is treated as "no filter"
144
- const results = [];
145
+ const allSubscriptions = [];
145
146
  try {
146
147
  this.suppressSignInEvents = true;
147
148
  // Get the list of tenants from each account
@@ -154,35 +155,54 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
154
155
  if (shouldFilterTenants && !tenantIds.includes(tenantId)) {
155
156
  continue;
156
157
  }
157
- // If the user is not signed in to this tenant, then skip it
158
- if (!(yield this.isSignedIn(tenantId, account))) {
159
- continue;
160
- }
161
158
  // For each tenant, get the list of subscriptions
162
- results.push(...yield this.getSubscriptionsForTenant(tenantId, account));
159
+ allSubscriptions.push(...yield this.getSubscriptionsForTenant(account, tenantId));
163
160
  }
161
+ // list subscriptions for the home tenant
162
+ allSubscriptions.push(...yield this.getSubscriptionsForTenant(account));
164
163
  }
165
164
  }
166
165
  finally {
167
166
  this.suppressSignInEvents = false;
168
167
  }
168
+ // It's possible that by listing subscriptions in all tenants and the "home" tenant there could be duplicate subscriptions
169
+ // Thus, we remove duplicate subscriptions. However, if multiple accounts have the same subscription, we keep them.
170
+ const subscriptionMap = new Map();
171
+ allSubscriptions.forEach(sub => subscriptionMap.set(`${sub.account.id}/${sub.subscriptionId}`, sub));
172
+ const uniqueSubscriptions = Array.from(subscriptionMap.values());
169
173
  const sortSubscriptions = (subscriptions) => subscriptions.sort((a, b) => a.name.localeCompare(b.name));
170
174
  const subscriptionIds = yield this.getSubscriptionFilters();
171
175
  if (filter && !!subscriptionIds.length) { // If the list is empty it is treated as "no filter"
172
- return sortSubscriptions(results.filter(sub => subscriptionIds.includes(sub.subscriptionId)));
176
+ return sortSubscriptions(uniqueSubscriptions.filter(sub => subscriptionIds.includes(sub.subscriptionId)));
173
177
  }
174
- return sortSubscriptions(results);
178
+ return sortSubscriptions(uniqueSubscriptions);
175
179
  });
176
180
  }
177
181
  /**
178
182
  * Checks to see if a user is signed in.
179
183
  *
180
184
  * @param tenantId (Optional) Provide to check if a user is signed in to a specific tenant.
185
+ * @param account (Optional) Provide to check if a user is signed in to a specific account.
181
186
  *
182
187
  * @returns True if the user is signed in, false otherwise.
188
+ *
189
+ * If no tenant or account is provided, then
190
+ * checks all accounts for a session.
183
191
  */
184
192
  isSignedIn(tenantId, account) {
185
193
  return __awaiter(this, void 0, void 0, function* () {
194
+ // If no tenant or account is provided, then check all accounts for a session
195
+ if (!account && !tenantId) {
196
+ const accounts = yield vscode.authentication.getAccounts((0, configuredAzureEnv_1.getConfiguredAuthProviderId)());
197
+ if (accounts.length === 0) {
198
+ return false;
199
+ }
200
+ for (const account of accounts) {
201
+ if (yield this.isSignedIn(undefined, account)) {
202
+ return true;
203
+ }
204
+ }
205
+ }
186
206
  const session = yield (0, getSessionFromVSCode_1.getSessionFromVSCode)([], tenantId, { createIfNone: false, silent: true, account });
187
207
  return !!session;
188
208
  });
@@ -191,12 +211,18 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
191
211
  * Asks the user to sign in or pick an account to use.
192
212
  *
193
213
  * @param tenantId (Optional) Provide to sign in to a specific tenant.
214
+ * @param account (Optional) Provide to sign in to a specific account.
194
215
  *
195
216
  * @returns True if the user is signed in, false otherwise.
196
217
  */
197
- signIn(tenantId) {
218
+ signIn(tenantId, account) {
198
219
  return __awaiter(this, void 0, void 0, function* () {
199
- const session = yield (0, getSessionFromVSCode_1.getSessionFromVSCode)([], tenantId, { createIfNone: true, clearSessionPreference: true });
220
+ const session = yield (0, getSessionFromVSCode_1.getSessionFromVSCode)([], tenantId, {
221
+ createIfNone: true,
222
+ // If no account is provided, then clear the session preference which tells VS Code to show the account picker
223
+ clearSessionPreference: !account,
224
+ account,
225
+ });
200
226
  return !!session;
201
227
  });
202
228
  }
@@ -248,9 +274,14 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
248
274
  *
249
275
  * @returns The list of subscriptions for the tenant.
250
276
  */
251
- getSubscriptionsForTenant(tenantId, account) {
277
+ getSubscriptionsForTenant(account, tenantId) {
252
278
  var _a, e_3, _b, _c;
253
279
  return __awaiter(this, void 0, void 0, function* () {
280
+ // If the user is not signed in to this tenant or account, then return an empty list
281
+ // This is to prevent the NotSignedInError from being thrown in getSubscriptionClient
282
+ if (!(yield this.isSignedIn(tenantId, account))) {
283
+ return [];
284
+ }
254
285
  const { client, credential, authentication } = yield this.getSubscriptionClient(account, tenantId, undefined);
255
286
  const environment = (0, configuredAzureEnv_1.getConfiguredAzureEnv)();
256
287
  const subscriptions = [];
@@ -268,8 +299,8 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
268
299
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
269
300
  name: subscription.displayName,
270
301
  subscriptionId: subscription.subscriptionId,
302
+ tenantId: tenantId !== null && tenantId !== void 0 ? tenantId : subscription.tenantId,
271
303
  /* eslint-enable @typescript-eslint/no-non-null-assertion */
272
- tenantId: tenantId,
273
304
  account: account
274
305
  });
275
306
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@microsoft/vscode-azext-azureauth",
3
3
  "author": "Microsoft Corporation",
4
- "version": "3.0.1",
4
+ "version": "3.1.0",
5
5
  "description": "Azure authentication helpers for Visual Studio Code",
6
6
  "tags": [
7
7
  "azure",