@microsoft/vscode-azext-azureauth 6.0.0-alpha.2 → 6.0.0-alpha.4

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.
@@ -41,6 +41,7 @@ exports.AzureDevOpsSubscriptionProvider = void 0;
41
41
  exports.createAzureDevOpsSubscriptionProviderFactory = createAzureDevOpsSubscriptionProviderFactory;
42
42
  const azureEnv = __importStar(require("@azure/ms-rest-azure-env")); // This package is so small that it's not worth lazy loading
43
43
  const crypto = __importStar(require("crypto"));
44
+ const configuredAzureEnv_1 = require("../utils/configuredAzureEnv");
44
45
  const isAuthenticationWwwAuthenticateRequest_1 = require("../utils/isAuthenticationWwwAuthenticateRequest");
45
46
  const NotSignedInError_1 = require("../utils/NotSignedInError");
46
47
  const AzureSubscriptionProviderBase_1 = require("./AzureSubscriptionProviderBase");
@@ -90,6 +91,7 @@ class AzureDevOpsSubscriptionProvider extends AzureSubscriptionProviderBase_1.Az
90
91
  {
91
92
  id: 'test-account-id',
92
93
  label: 'test-account',
94
+ environment: new configuredAzureEnv_1.ExtendedEnvironment(azureEnv.Environment.AzureCloud, false),
93
95
  }
94
96
  ]);
95
97
  }
@@ -38,6 +38,7 @@ var __importStar = (this && this.__importStar) || (function () {
38
38
  })();
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
40
  exports.AzureSubscriptionProviderBase = void 0;
41
+ const util_1 = require("util");
41
42
  const vscode = __importStar(require("vscode"));
42
43
  const AzureSubscriptionProviderRequestOptions_1 = require("../contracts/AzureSubscriptionProviderRequestOptions");
43
44
  const configuredAzureEnv_1 = require("../utils/configuredAzureEnv");
@@ -165,7 +166,9 @@ class AzureSubscriptionProviderBase {
165
166
  this.logForTenant(tenant, 'Skipping account+tenant because it is not signed in');
166
167
  return;
167
168
  }
168
- throw err;
169
+ // Don't rethrow--skip tenants that fail for other reasons
170
+ // (e.g., locked account) so remaining tenants can still be listed
171
+ this.errorForTenant(tenant, 'Skipping account+tenant due to error', err);
169
172
  }
170
173
  }));
171
174
  }
@@ -175,6 +178,8 @@ class AzureSubscriptionProviderBase {
175
178
  this.logForAccount(account, 'Skipping account because it is not signed in');
176
179
  return;
177
180
  }
181
+ // Log and skip accounts that fail for other reasons (e.g., locked account)
182
+ this.errorForAccount(account, 'Skipping account due to error', err);
178
183
  }
179
184
  }));
180
185
  }
@@ -198,7 +203,13 @@ class AzureSubscriptionProviderBase {
198
203
  const startTime = Date.now();
199
204
  this.log('Fetching accounts...');
200
205
  this.silenceRefreshEvents();
201
- const results = await vscode.authentication.getAccounts((0, configuredAzureEnv_1.getConfiguredAuthProviderId)());
206
+ const environment = (0, configuredAzureEnv_1.getConfiguredAzureEnv)();
207
+ const results = (await vscode.authentication.getAccounts((0, configuredAzureEnv_1.getConfiguredAuthProviderId)())).map(account => {
208
+ return {
209
+ ...account,
210
+ environment,
211
+ };
212
+ });
202
213
  if (results.length === 0) {
203
214
  this.log('No accounts found');
204
215
  throw new NotSignedInError_1.NotSignedInError();
@@ -292,7 +303,6 @@ class AzureSubscriptionProviderBase {
292
303
  name: subscription.displayName,
293
304
  subscriptionId: subscription.subscriptionId,
294
305
  /* eslint-enable @typescript-eslint/no-non-null-assertion */
295
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
296
306
  tenantId: subscription.tenantId || tenant.tenantId, // In rare cases, a subscription may be listed but come from a different tenant
297
307
  account: tenant.account,
298
308
  });
@@ -314,11 +324,13 @@ class AzureSubscriptionProviderBase {
314
324
  * @returns A {@link SubscriptionClient}, {@link TokenCredential}, and {@link AzureAuthentication} for the given account+tenant.
315
325
  */
316
326
  async getSubscriptionClient(tenant) {
327
+ // Credential ignores requested scopes and always uses default scopes (managementEndpointUrl),
328
+ // matching the scope used during signIn(). This avoids a refresh token round-trip that can
329
+ // fail when MSAL has stale cache entries for a different scope.
317
330
  const credential = {
318
- getToken: async (scopes, options) => {
331
+ getToken: async (_scopes, options) => {
319
332
  this.silenceRefreshEvents();
320
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
321
- const session = await (0, getSessionFromVSCode_1.getSessionFromVSCode)(scopes, options?.tenantId || tenant.tenantId, { createIfNone: false, silent: true, account: tenant.account });
333
+ const session = await (0, getSessionFromVSCode_1.getSessionFromVSCode)(undefined, options?.tenantId || tenant.tenantId, { createIfNone: false, silent: true, account: tenant.account });
322
334
  if (!session) {
323
335
  throw new NotSignedInError_1.NotSignedInError();
324
336
  }
@@ -364,6 +376,30 @@ class AzureSubscriptionProviderBase {
364
376
  logForTenant(tenant, message) {
365
377
  this.logger?.debug(`[auth] [account: ${(0, screen_1.screen)(tenant.account)}] [tenant: ${(0, screen_1.screen)(tenant)}] ${message}`);
366
378
  }
379
+ warnForAccount(account, message) {
380
+ this.logger?.warn(`[auth] [account: ${(0, screen_1.screen)(account)}] ${message}`);
381
+ }
382
+ warnForTenant(tenant, message) {
383
+ this.logger?.warn(`[auth] [account: ${(0, screen_1.screen)(tenant.account)}] [tenant: ${(0, screen_1.screen)(tenant)}] ${message}`);
384
+ }
385
+ errorForAccount(account, message, err) {
386
+ this.logger?.error(`[auth] [account: ${(0, screen_1.screen)(account)}] ${message}`);
387
+ if (err instanceof Error) {
388
+ this.logger?.error(err);
389
+ }
390
+ else {
391
+ this.logger?.error(`[auth] [account: ${(0, screen_1.screen)(account)}] ${(0, util_1.inspect)(err)}`);
392
+ }
393
+ }
394
+ errorForTenant(tenant, message, err) {
395
+ this.logger?.error(`[auth] [account: ${(0, screen_1.screen)(tenant.account)}] [tenant: ${(0, screen_1.screen)(tenant)}] ${message}`);
396
+ if (err instanceof Error) {
397
+ this.logger?.error(err);
398
+ }
399
+ else {
400
+ this.logger?.error(`[auth] [account: ${(0, screen_1.screen)(tenant.account)}] [tenant: ${(0, screen_1.screen)(tenant)}] ${(0, util_1.inspect)(err)}`);
401
+ }
402
+ }
367
403
  throwIfCancelled(token) {
368
404
  if (token?.isCancellationRequested) {
369
405
  throw new vscode.CancellationError();
@@ -37,6 +37,7 @@ var __importStar = (this && this.__importStar) || (function () {
37
37
  };
38
38
  })();
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.ExtendedEnvironment = void 0;
40
41
  exports.getConfiguredAzureEnv = getConfiguredAzureEnv;
41
42
  exports.setConfiguredAzureEnv = setConfiguredAzureEnv;
42
43
  exports.getConfiguredAuthProviderId = getConfiguredAuthProviderId;
@@ -62,6 +63,7 @@ class ExtendedEnvironment extends azureEnv.Environment {
62
63
  Object.assign(this, parameters);
63
64
  }
64
65
  }
66
+ exports.ExtendedEnvironment = ExtendedEnvironment;
65
67
  /**
66
68
  * Gets the configured Azure environment.
67
69
  *
@@ -1,5 +1,8 @@
1
1
  import type * as vscode from 'vscode';
2
+ import type { ExtendedEnvironment } from '../utils/configuredAzureEnv';
2
3
  /**
3
4
  * A shortcut type for {@link vscode.AuthenticationSessionAccountInformation}
4
5
  */
5
- export type AzureAccount = Readonly<vscode.AuthenticationSessionAccountInformation>;
6
+ export type AzureAccount = Readonly<vscode.AuthenticationSessionAccountInformation> & {
7
+ readonly environment: ExtendedEnvironment;
8
+ };
@@ -4,6 +4,7 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as azureEnv from '@azure/ms-rest-azure-env'; // This package is so small that it's not worth lazy loading
6
6
  import * as crypto from 'crypto';
7
+ import { ExtendedEnvironment } from '../utils/configuredAzureEnv';
7
8
  import { isAuthenticationWwwAuthenticateRequest } from '../utils/isAuthenticationWwwAuthenticateRequest';
8
9
  import { NotSignedInError } from '../utils/NotSignedInError';
9
10
  import { AzureSubscriptionProviderBase } from './AzureSubscriptionProviderBase';
@@ -53,6 +54,7 @@ export class AzureDevOpsSubscriptionProvider extends AzureSubscriptionProviderBa
53
54
  {
54
55
  id: 'test-account-id',
55
56
  label: 'test-account',
57
+ environment: new ExtendedEnvironment(azureEnv.Environment.AzureCloud, false),
56
58
  }
57
59
  ]);
58
60
  }
@@ -67,6 +67,10 @@ export declare abstract class AzureSubscriptionProviderBase implements AzureSubs
67
67
  protected log(message: string): void;
68
68
  protected logForAccount(account: AzureAccount, message: string): void;
69
69
  protected logForTenant(tenant: TenantIdAndAccount, message: string): void;
70
+ protected warnForAccount(account: AzureAccount, message: string): void;
71
+ protected warnForTenant(tenant: TenantIdAndAccount, message: string): void;
72
+ protected errorForAccount(account: AzureAccount, message: string, err: unknown): void;
73
+ protected errorForTenant(tenant: TenantIdAndAccount, message: string, err: unknown): void;
70
74
  protected throwIfCancelled(token: vscode.CancellationToken | undefined): void;
71
75
  private timeout;
72
76
  private silenceRefreshEvents;
@@ -2,6 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
+ import { inspect } from 'util';
5
6
  import * as vscode from 'vscode';
6
7
  import { DefaultOptions, DefaultSignInOptions } from '../contracts/AzureSubscriptionProviderRequestOptions';
7
8
  import { getConfiguredAuthProviderId, getConfiguredAzureEnv } from '../utils/configuredAzureEnv';
@@ -129,7 +130,9 @@ export class AzureSubscriptionProviderBase {
129
130
  this.logForTenant(tenant, 'Skipping account+tenant because it is not signed in');
130
131
  return;
131
132
  }
132
- throw err;
133
+ // Don't rethrow--skip tenants that fail for other reasons
134
+ // (e.g., locked account) so remaining tenants can still be listed
135
+ this.errorForTenant(tenant, 'Skipping account+tenant due to error', err);
133
136
  }
134
137
  }));
135
138
  }
@@ -139,6 +142,8 @@ export class AzureSubscriptionProviderBase {
139
142
  this.logForAccount(account, 'Skipping account because it is not signed in');
140
143
  return;
141
144
  }
145
+ // Log and skip accounts that fail for other reasons (e.g., locked account)
146
+ this.errorForAccount(account, 'Skipping account due to error', err);
142
147
  }
143
148
  }));
144
149
  }
@@ -162,7 +167,13 @@ export class AzureSubscriptionProviderBase {
162
167
  const startTime = Date.now();
163
168
  this.log('Fetching accounts...');
164
169
  this.silenceRefreshEvents();
165
- const results = await vscode.authentication.getAccounts(getConfiguredAuthProviderId());
170
+ const environment = getConfiguredAzureEnv();
171
+ const results = (await vscode.authentication.getAccounts(getConfiguredAuthProviderId())).map(account => {
172
+ return {
173
+ ...account,
174
+ environment,
175
+ };
176
+ });
166
177
  if (results.length === 0) {
167
178
  this.log('No accounts found');
168
179
  throw new NotSignedInError();
@@ -256,7 +267,6 @@ export class AzureSubscriptionProviderBase {
256
267
  name: subscription.displayName,
257
268
  subscriptionId: subscription.subscriptionId,
258
269
  /* eslint-enable @typescript-eslint/no-non-null-assertion */
259
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
260
270
  tenantId: subscription.tenantId || tenant.tenantId, // In rare cases, a subscription may be listed but come from a different tenant
261
271
  account: tenant.account,
262
272
  });
@@ -278,11 +288,13 @@ export class AzureSubscriptionProviderBase {
278
288
  * @returns A {@link SubscriptionClient}, {@link TokenCredential}, and {@link AzureAuthentication} for the given account+tenant.
279
289
  */
280
290
  async getSubscriptionClient(tenant) {
291
+ // Credential ignores requested scopes and always uses default scopes (managementEndpointUrl),
292
+ // matching the scope used during signIn(). This avoids a refresh token round-trip that can
293
+ // fail when MSAL has stale cache entries for a different scope.
281
294
  const credential = {
282
- getToken: async (scopes, options) => {
295
+ getToken: async (_scopes, options) => {
283
296
  this.silenceRefreshEvents();
284
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
285
- const session = await getSessionFromVSCode(scopes, options?.tenantId || tenant.tenantId, { createIfNone: false, silent: true, account: tenant.account });
297
+ const session = await getSessionFromVSCode(undefined, options?.tenantId || tenant.tenantId, { createIfNone: false, silent: true, account: tenant.account });
286
298
  if (!session) {
287
299
  throw new NotSignedInError();
288
300
  }
@@ -328,6 +340,30 @@ export class AzureSubscriptionProviderBase {
328
340
  logForTenant(tenant, message) {
329
341
  this.logger?.debug(`[auth] [account: ${screen(tenant.account)}] [tenant: ${screen(tenant)}] ${message}`);
330
342
  }
343
+ warnForAccount(account, message) {
344
+ this.logger?.warn(`[auth] [account: ${screen(account)}] ${message}`);
345
+ }
346
+ warnForTenant(tenant, message) {
347
+ this.logger?.warn(`[auth] [account: ${screen(tenant.account)}] [tenant: ${screen(tenant)}] ${message}`);
348
+ }
349
+ errorForAccount(account, message, err) {
350
+ this.logger?.error(`[auth] [account: ${screen(account)}] ${message}`);
351
+ if (err instanceof Error) {
352
+ this.logger?.error(err);
353
+ }
354
+ else {
355
+ this.logger?.error(`[auth] [account: ${screen(account)}] ${inspect(err)}`);
356
+ }
357
+ }
358
+ errorForTenant(tenant, message, err) {
359
+ this.logger?.error(`[auth] [account: ${screen(tenant.account)}] [tenant: ${screen(tenant)}] ${message}`);
360
+ if (err instanceof Error) {
361
+ this.logger?.error(err);
362
+ }
363
+ else {
364
+ this.logger?.error(`[auth] [account: ${screen(tenant.account)}] [tenant: ${screen(tenant)}] ${inspect(err)}`);
365
+ }
366
+ }
331
367
  throwIfCancelled(token) {
332
368
  if (token?.isCancellationRequested) {
333
369
  throw new vscode.CancellationError();
@@ -1,6 +1,6 @@
1
1
  import * as azureEnv from '@azure/ms-rest-azure-env';
2
2
  import * as vscode from 'vscode';
3
- declare class ExtendedEnvironment extends azureEnv.Environment {
3
+ export declare class ExtendedEnvironment extends azureEnv.Environment {
4
4
  readonly isCustomCloud: boolean;
5
5
  constructor(parameters: azureEnv.EnvironmentParameters, isCustomCloud: boolean);
6
6
  }
@@ -24,4 +24,3 @@ export declare function setConfiguredAzureEnv(cloud: 'AzureCloud' | 'ChinaCloud'
24
24
  * @returns The provider ID to use, either `'microsoft'` or `'microsoft-sovereign-cloud'`
25
25
  */
26
26
  export declare function getConfiguredAuthProviderId(): string;
27
- export {};
@@ -14,7 +14,7 @@ var CloudEnvironmentSettingValue;
14
14
  CloudEnvironmentSettingValue["USGovernment"] = "USGovernment";
15
15
  CloudEnvironmentSettingValue["Custom"] = "custom";
16
16
  })(CloudEnvironmentSettingValue || (CloudEnvironmentSettingValue = {}));
17
- class ExtendedEnvironment extends azureEnv.Environment {
17
+ export class ExtendedEnvironment extends azureEnv.Environment {
18
18
  isCustomCloud;
19
19
  constructor(parameters, isCustomCloud) {
20
20
  super(parameters);
@@ -6,4 +6,4 @@ import type { AzureTenant } from '../contracts/AzureTenant';
6
6
  * @param accountOrTenant The account or tenant to screen the label / display name of
7
7
  * @returns The screened label / display name
8
8
  */
9
- export declare function screen(accountOrTenant: AzureAccount | AzureTenant): string;
9
+ export declare function screen(accountOrTenant: Pick<AzureAccount, 'id' | 'label'> | Pick<AzureTenant, 'tenantId' | 'displayName'>): string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@microsoft/vscode-azext-azureauth",
3
3
  "author": "Microsoft Corporation",
4
- "version": "6.0.0-alpha.2",
4
+ "version": "6.0.0-alpha.4",
5
5
  "description": "Azure authentication helpers for Visual Studio Code",
6
6
  "tags": [
7
7
  "azure",
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "devDependencies": {
51
51
  "@azure/core-auth": "^1.10.1",
52
- "@microsoft/vscode-azext-eng": "1.0.0-alpha.4",
52
+ "@microsoft/vscode-azext-eng": "1.0.0-alpha.13",
53
53
  "@types/node": "22.x",
54
54
  "@types/vscode": "1.106.0"
55
55
  },