@azure/identity 4.1.0-alpha.20240229.2 → 4.1.0-alpha.20240305.3

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.

Potentially problematic release.


This version of @azure/identity might be problematic. Click here for more details.

package/dist/index.js CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var msalCommon = require('@azure/msal-node');
6
5
  var logger$q = require('@azure/logger');
7
- var coreUtil = require('@azure/core-util');
8
- var abortController = require('@azure/abort-controller');
9
6
  var coreClient = require('@azure/core-client');
7
+ var coreUtil = require('@azure/core-util');
10
8
  var coreRestPipeline = require('@azure/core-rest-pipeline');
9
+ var abortController = require('@azure/abort-controller');
11
10
  var coreTracing = require('@azure/core-tracing');
12
11
  var fs = require('fs');
13
12
  var os = require('os');
14
13
  var path = require('path');
14
+ var msalCommon = require('@azure/msal-node');
15
15
  var promises = require('fs/promises');
16
16
  var https = require('https');
17
17
  var child_process = require('child_process');
@@ -42,62 +42,38 @@ var child_process__namespace = /*#__PURE__*/_interopNamespaceDefault(child_proce
42
42
  // Copyright (c) Microsoft Corporation.
43
43
  // Licensed under the MIT license.
44
44
  /**
45
- * Current version of the `@azure/identity` package.
46
- */
47
- const SDK_VERSION = `4.1.0-beta.2`;
48
- /**
49
- * The default client ID for authentication
50
- * @internal
51
- */
52
- // TODO: temporary - this is the Azure CLI clientID - we'll replace it when
53
- // Developer Sign On application is available
54
- // https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Constants.cs#L9
55
- const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
56
- /**
57
- * The default tenant for authentication
58
- * @internal
59
- */
60
- const DefaultTenantId = "common";
61
- /**
62
- * A list of known Azure authority hosts
63
- */
64
- exports.AzureAuthorityHosts = void 0;
65
- (function (AzureAuthorityHosts) {
66
- /**
67
- * China-based Azure Authority Host
68
- */
69
- AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
70
- /**
71
- * Germany-based Azure Authority Host
72
- */
73
- AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
74
- /**
75
- * US Government Azure Authority Host
76
- */
77
- AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
78
- /**
79
- * Public Cloud Azure Authority Host
80
- */
81
- AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
82
- })(exports.AzureAuthorityHosts || (exports.AzureAuthorityHosts = {}));
83
- /**
45
+ * The current persistence provider, undefined by default.
84
46
  * @internal
85
- * The default authority host.
86
47
  */
87
- const DefaultAuthorityHost = exports.AzureAuthorityHosts.AzurePublicCloud;
48
+ let persistenceProvider = undefined;
88
49
  /**
50
+ * An object that allows setting the persistence provider.
89
51
  * @internal
90
- * Allow acquiring tokens for any tenant for multi-tentant auth.
91
52
  */
92
- const ALL_TENANTS = ["*"];
53
+ const msalNodeFlowCacheControl = {
54
+ setPersistence(pluginProvider) {
55
+ persistenceProvider = pluginProvider;
56
+ },
57
+ };
93
58
  /**
59
+ * The current native broker provider, undefined by default.
94
60
  * @internal
95
61
  */
96
- const CACHE_CAE_SUFFIX = ".cae";
62
+ let nativeBrokerInfo = undefined;
63
+ function hasNativeBroker() {
64
+ return nativeBrokerInfo !== undefined;
65
+ }
97
66
  /**
67
+ * An object that allows setting the native broker provider.
98
68
  * @internal
99
69
  */
100
- const CACHE_NON_CAE_SUFFIX = ".nocae";
70
+ const msalNodeFlowNativeBrokerControl = {
71
+ setNativeBroker(broker) {
72
+ nativeBrokerInfo = {
73
+ broker,
74
+ };
75
+ },
76
+ };
101
77
 
102
78
  // Copyright (c) Microsoft Corporation.
103
79
  // Licensed under the MIT license.
@@ -178,6 +154,66 @@ function credentialLogger(title, log = logger$p) {
178
154
  return Object.assign(Object.assign({}, credLogger), { parent: log, getToken: credentialLoggerInstance("=> getToken()", credLogger, log) });
179
155
  }
180
156
 
157
+ // Copyright (c) Microsoft Corporation.
158
+ // Licensed under the MIT license.
159
+ /**
160
+ * Current version of the `@azure/identity` package.
161
+ */
162
+ const SDK_VERSION = `4.1.0-beta.2`;
163
+ /**
164
+ * The default client ID for authentication
165
+ * @internal
166
+ */
167
+ // TODO: temporary - this is the Azure CLI clientID - we'll replace it when
168
+ // Developer Sign On application is available
169
+ // https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Constants.cs#L9
170
+ const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
171
+ /**
172
+ * The default tenant for authentication
173
+ * @internal
174
+ */
175
+ const DefaultTenantId = "common";
176
+ /**
177
+ * A list of known Azure authority hosts
178
+ */
179
+ exports.AzureAuthorityHosts = void 0;
180
+ (function (AzureAuthorityHosts) {
181
+ /**
182
+ * China-based Azure Authority Host
183
+ */
184
+ AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
185
+ /**
186
+ * Germany-based Azure Authority Host
187
+ */
188
+ AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
189
+ /**
190
+ * US Government Azure Authority Host
191
+ */
192
+ AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
193
+ /**
194
+ * Public Cloud Azure Authority Host
195
+ */
196
+ AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
197
+ })(exports.AzureAuthorityHosts || (exports.AzureAuthorityHosts = {}));
198
+ /**
199
+ * @internal
200
+ * The default authority host.
201
+ */
202
+ const DefaultAuthorityHost = exports.AzureAuthorityHosts.AzurePublicCloud;
203
+ /**
204
+ * @internal
205
+ * Allow acquiring tokens for any tenant for multi-tentant auth.
206
+ */
207
+ const ALL_TENANTS = ["*"];
208
+ /**
209
+ * @internal
210
+ */
211
+ const CACHE_CAE_SUFFIX = ".cae";
212
+ /**
213
+ * @internal
214
+ */
215
+ const CACHE_NON_CAE_SUFFIX = ".nocae";
216
+
181
217
  // Copyright (c) Microsoft Corporation.
182
218
  // Licensed under the MIT license.
183
219
  function isErrorResponse(errorResponse) {
@@ -299,325 +335,113 @@ class AuthenticationRequiredError extends Error {
299
335
 
300
336
  // Copyright (c) Microsoft Corporation.
301
337
  // Licensed under the MIT license.
338
+ function createConfigurationErrorMessage(tenantId) {
339
+ return `The current credential is not configured to acquire tokens for tenant ${tenantId}. To enable acquiring tokens for this tenant add it to the AdditionallyAllowedTenants on the credential options, or add "*" to AdditionallyAllowedTenants to allow acquiring tokens for any tenant.`;
340
+ }
302
341
  /**
342
+ * Of getToken contains a tenantId, this functions allows picking this tenantId as the appropriate for authentication,
343
+ * unless multitenant authentication has been disabled through the AZURE_IDENTITY_DISABLE_MULTITENANTAUTH (on Node.js),
344
+ * or unless the original tenant Id is `adfs`.
303
345
  * @internal
304
346
  */
305
- const logger$o = credentialLogger("IdentityUtils");
347
+ function processMultiTenantRequest(tenantId, getTokenOptions, additionallyAllowedTenantIds = [], logger) {
348
+ var _a;
349
+ let resolvedTenantId;
350
+ if (process.env.AZURE_IDENTITY_DISABLE_MULTITENANTAUTH) {
351
+ resolvedTenantId = tenantId;
352
+ }
353
+ else if (tenantId === "adfs") {
354
+ resolvedTenantId = tenantId;
355
+ }
356
+ else {
357
+ resolvedTenantId = (_a = getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.tenantId) !== null && _a !== void 0 ? _a : tenantId;
358
+ }
359
+ if (tenantId &&
360
+ resolvedTenantId !== tenantId &&
361
+ !additionallyAllowedTenantIds.includes("*") &&
362
+ !additionallyAllowedTenantIds.some((t) => t.localeCompare(resolvedTenantId) === 0)) {
363
+ const message = createConfigurationErrorMessage(tenantId);
364
+ logger === null || logger === void 0 ? void 0 : logger.info(message);
365
+ throw new CredentialUnavailableError(message);
366
+ }
367
+ return resolvedTenantId;
368
+ }
369
+
370
+ // Copyright (c) Microsoft Corporation.
371
+ // Licensed under the MIT license.
306
372
  /**
307
- * Latest AuthenticationRecord version
308
373
  * @internal
309
374
  */
310
- const LatestAuthenticationRecordVersion = "1.0";
375
+ function checkTenantId(logger, tenantId) {
376
+ if (!tenantId.match(/^[0-9a-zA-Z-.]+$/)) {
377
+ const error = new Error("Invalid tenant id provided. You can locate your tenant id by following the instructions listed here: https://learn.microsoft.com/partner-center/find-ids-and-domain-names.");
378
+ logger.info(formatError("", error));
379
+ throw error;
380
+ }
381
+ }
311
382
  /**
312
- * Ensures the validity of the MSAL token
313
383
  * @internal
314
384
  */
315
- function ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
316
- const error = (message) => {
317
- logger$o.getToken.info(message);
318
- return new AuthenticationRequiredError({
319
- scopes: Array.isArray(scopes) ? scopes : [scopes],
320
- getTokenOptions,
321
- message,
322
- });
323
- };
324
- if (!msalToken) {
325
- throw error("No response");
385
+ function resolveTenantId(logger, tenantId, clientId) {
386
+ if (tenantId) {
387
+ checkTenantId(logger, tenantId);
388
+ return tenantId;
326
389
  }
327
- if (!msalToken.expiresOn) {
328
- throw error(`Response had no "expiresOn" property.`);
390
+ if (!clientId) {
391
+ clientId = DeveloperSignOnClientId;
329
392
  }
330
- if (!msalToken.accessToken) {
331
- throw error(`Response had no "accessToken" property.`);
393
+ if (clientId !== DeveloperSignOnClientId) {
394
+ return "common";
332
395
  }
396
+ return "organizations";
333
397
  }
334
398
  /**
335
- * Generates a valid authority by combining a host with a tenantId.
336
399
  * @internal
337
400
  */
338
- function getAuthority(tenantId, host) {
339
- if (!host) {
340
- host = DefaultAuthorityHost;
401
+ function resolveAdditionallyAllowedTenantIds(additionallyAllowedTenants) {
402
+ if (!additionallyAllowedTenants || additionallyAllowedTenants.length === 0) {
403
+ return [];
341
404
  }
342
- if (new RegExp(`${tenantId}/?$`).test(host)) {
343
- return host;
405
+ if (additionallyAllowedTenants.includes("*")) {
406
+ return ALL_TENANTS;
344
407
  }
345
- if (host.endsWith("/")) {
346
- return host + tenantId;
408
+ return additionallyAllowedTenants;
409
+ }
410
+
411
+ // Copyright (c) Microsoft Corporation.
412
+ // Licensed under the MIT license.
413
+ function getIdentityTokenEndpointSuffix(tenantId) {
414
+ if (tenantId === "adfs") {
415
+ return "oauth2/token";
347
416
  }
348
417
  else {
349
- return `${host}/${tenantId}`;
418
+ return "oauth2/v2.0/token";
350
419
  }
351
420
  }
421
+
422
+ // Copyright (c) Microsoft Corporation.
423
+ // Licensed under the MIT license.
352
424
  /**
353
- * Generates the known authorities.
354
- * If the Tenant Id is `adfs`, the authority can't be validated since the format won't match the expected one.
355
- * For that reason, we have to force MSAL to disable validating the authority
356
- * by sending it within the known authorities in the MSAL configuration.
425
+ * Creates a span using the global tracer.
357
426
  * @internal
358
427
  */
359
- function getKnownAuthorities(tenantId, authorityHost, disableInstanceDiscovery) {
360
- if ((tenantId === "adfs" && authorityHost) || disableInstanceDiscovery) {
361
- return [authorityHost];
362
- }
363
- return [];
364
- }
365
- /**
366
- * Generates a logger that can be passed to the MSAL clients.
367
- * @param credLogger - The logger of the credential.
368
- * @internal
369
- */
370
- const defaultLoggerCallback = (credLogger, platform = coreUtil.isNode ? "Node" : "Browser") => (level, message, containsPii) => {
371
- if (containsPii) {
372
- return;
373
- }
374
- switch (level) {
375
- case msalCommon__namespace.LogLevel.Error:
376
- credLogger.info(`MSAL ${platform} V2 error: ${message}`);
377
- return;
378
- case msalCommon__namespace.LogLevel.Info:
379
- credLogger.info(`MSAL ${platform} V2 info message: ${message}`);
380
- return;
381
- case msalCommon__namespace.LogLevel.Verbose:
382
- credLogger.info(`MSAL ${platform} V2 verbose message: ${message}`);
383
- return;
384
- case msalCommon__namespace.LogLevel.Warning:
385
- credLogger.info(`MSAL ${platform} V2 warning: ${message}`);
386
- return;
387
- }
388
- };
389
- /**
390
- * @internal
391
- */
392
- function getMSALLogLevel(logLevel) {
393
- switch (logLevel) {
394
- case "error":
395
- return msalCommon__namespace.LogLevel.Error;
396
- case "info":
397
- return msalCommon__namespace.LogLevel.Info;
398
- case "verbose":
399
- return msalCommon__namespace.LogLevel.Verbose;
400
- case "warning":
401
- return msalCommon__namespace.LogLevel.Warning;
402
- default:
403
- // default msal logging level should be Info
404
- return msalCommon__namespace.LogLevel.Info;
405
- }
406
- }
407
- /**
408
- * Wraps core-util's randomUUID in order to allow for mocking in tests.
409
- * This prepares the library for the upcoming core-util update to ESM.
410
- *
411
- * @internal
412
- * @returns A string containing a random UUID
413
- */
414
- function randomUUID() {
415
- return coreUtil.randomUUID();
416
- }
417
- /**
418
- * Handles MSAL errors.
419
- */
420
- function handleMsalError(scopes, error, getTokenOptions) {
421
- if (error.name === "AuthError" ||
422
- error.name === "ClientAuthError" ||
423
- error.name === "BrowserAuthError") {
424
- const msalError = error;
425
- switch (msalError.errorCode) {
426
- case "endpoints_resolution_error":
427
- logger$o.info(formatError(scopes, error.message));
428
- return new CredentialUnavailableError(error.message);
429
- case "device_code_polling_cancelled":
430
- return new abortController.AbortError("The authentication has been aborted by the caller.");
431
- case "consent_required":
432
- case "interaction_required":
433
- case "login_required":
434
- logger$o.info(formatError(scopes, `Authentication returned errorCode ${msalError.errorCode}`));
435
- break;
436
- default:
437
- logger$o.info(formatError(scopes, `Failed to acquire token: ${error.message}`));
438
- break;
439
- }
440
- }
441
- if (error.name === "ClientConfigurationError" ||
442
- error.name === "BrowserConfigurationAuthError" ||
443
- error.name === "AbortError") {
444
- return error;
445
- }
446
- if (error.name === "NativeAuthError") {
447
- logger$o.info(formatError(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`));
448
- return error;
449
- }
450
- return new AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message });
451
- }
452
- // transformations.ts
453
- function publicToMsal(account) {
454
- const [environment] = account.authority.match(/([a-z]*\.[a-z]*\.[a-z]*)/) || [""];
455
- return Object.assign(Object.assign({}, account), { localAccountId: account.homeAccountId, environment });
456
- }
457
- function msalToPublic(clientId, account) {
458
- const record = {
459
- authority: getAuthority(account.tenantId, account.environment),
460
- homeAccountId: account.homeAccountId,
461
- tenantId: account.tenantId || DefaultTenantId,
462
- username: account.username,
463
- clientId,
464
- version: LatestAuthenticationRecordVersion,
465
- };
466
- return record;
467
- }
468
- /**
469
- * Serializes an `AuthenticationRecord` into a string.
470
- *
471
- * The output of a serialized authentication record will contain the following properties:
472
- *
473
- * - "authority"
474
- * - "homeAccountId"
475
- * - "clientId"
476
- * - "tenantId"
477
- * - "username"
478
- * - "version"
479
- *
480
- * To later convert this string to a serialized `AuthenticationRecord`, please use the exported function `deserializeAuthenticationRecord()`.
481
- */
482
- function serializeAuthenticationRecord(record) {
483
- return JSON.stringify(record);
484
- }
485
- /**
486
- * Deserializes a previously serialized authentication record from a string into an object.
487
- *
488
- * The input string must contain the following properties:
489
- *
490
- * - "authority"
491
- * - "homeAccountId"
492
- * - "clientId"
493
- * - "tenantId"
494
- * - "username"
495
- * - "version"
496
- *
497
- * If the version we receive is unsupported, an error will be thrown.
498
- *
499
- * At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
500
- *
501
- * @param serializedRecord - Authentication record previously serialized into string.
502
- * @returns AuthenticationRecord.
503
- */
504
- function deserializeAuthenticationRecord(serializedRecord) {
505
- const parsed = JSON.parse(serializedRecord);
506
- if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) {
507
- throw Error("Unsupported AuthenticationRecord version");
508
- }
509
- return parsed;
510
- }
511
-
512
- // Copyright (c) Microsoft Corporation.
513
- // Licensed under the MIT license.
514
- function createConfigurationErrorMessage(tenantId) {
515
- return `The current credential is not configured to acquire tokens for tenant ${tenantId}. To enable acquiring tokens for this tenant add it to the AdditionallyAllowedTenants on the credential options, or add "*" to AdditionallyAllowedTenants to allow acquiring tokens for any tenant.`;
516
- }
517
- /**
518
- * Of getToken contains a tenantId, this functions allows picking this tenantId as the appropriate for authentication,
519
- * unless multitenant authentication has been disabled through the AZURE_IDENTITY_DISABLE_MULTITENANTAUTH (on Node.js),
520
- * or unless the original tenant Id is `adfs`.
521
- * @internal
522
- */
523
- function processMultiTenantRequest(tenantId, getTokenOptions, additionallyAllowedTenantIds = [], logger) {
524
- var _a;
525
- let resolvedTenantId;
526
- if (process.env.AZURE_IDENTITY_DISABLE_MULTITENANTAUTH) {
527
- resolvedTenantId = tenantId;
528
- }
529
- else if (tenantId === "adfs") {
530
- resolvedTenantId = tenantId;
531
- }
532
- else {
533
- resolvedTenantId = (_a = getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.tenantId) !== null && _a !== void 0 ? _a : tenantId;
534
- }
535
- if (tenantId &&
536
- resolvedTenantId !== tenantId &&
537
- !additionallyAllowedTenantIds.includes("*") &&
538
- !additionallyAllowedTenantIds.some((t) => t.localeCompare(resolvedTenantId) === 0)) {
539
- const message = createConfigurationErrorMessage(tenantId);
540
- logger === null || logger === void 0 ? void 0 : logger.info(message);
541
- throw new CredentialUnavailableError(message);
542
- }
543
- return resolvedTenantId;
544
- }
545
-
546
- // Copyright (c) Microsoft Corporation.
547
- // Licensed under the MIT license.
548
- /**
549
- * @internal
550
- */
551
- function checkTenantId(logger, tenantId) {
552
- if (!tenantId.match(/^[0-9a-zA-Z-.]+$/)) {
553
- const error = new Error("Invalid tenant id provided. You can locate your tenant id by following the instructions listed here: https://learn.microsoft.com/partner-center/find-ids-and-domain-names.");
554
- logger.info(formatError("", error));
555
- throw error;
556
- }
557
- }
558
- /**
559
- * @internal
560
- */
561
- function resolveTenantId(logger, tenantId, clientId) {
562
- if (tenantId) {
563
- checkTenantId(logger, tenantId);
564
- return tenantId;
565
- }
566
- if (!clientId) {
567
- clientId = DeveloperSignOnClientId;
568
- }
569
- if (clientId !== DeveloperSignOnClientId) {
570
- return "common";
571
- }
572
- return "organizations";
573
- }
574
- /**
575
- * @internal
576
- */
577
- function resolveAdditionallyAllowedTenantIds(additionallyAllowedTenants) {
578
- if (!additionallyAllowedTenants || additionallyAllowedTenants.length === 0) {
579
- return [];
580
- }
581
- if (additionallyAllowedTenants.includes("*")) {
582
- return ALL_TENANTS;
583
- }
584
- return additionallyAllowedTenants;
585
- }
586
-
587
- // Copyright (c) Microsoft Corporation.
588
- // Licensed under the MIT license.
589
- function getIdentityTokenEndpointSuffix(tenantId) {
590
- if (tenantId === "adfs") {
591
- return "oauth2/token";
592
- }
593
- else {
594
- return "oauth2/v2.0/token";
595
- }
596
- }
597
-
598
- // Copyright (c) Microsoft Corporation.
599
- // Licensed under the MIT license.
600
- /**
601
- * Creates a span using the global tracer.
602
- * @internal
603
- */
604
- const tracingClient = coreTracing.createTracingClient({
605
- namespace: "Microsoft.AAD",
606
- packageName: "@azure/identity",
607
- packageVersion: SDK_VERSION,
608
- });
609
-
610
- // Copyright (c) Microsoft Corporation.
611
- // Licensed under the MIT license.
612
- const DefaultScopeSuffix = "/.default";
613
- const imdsHost = "http://169.254.169.254";
614
- const imdsEndpointPath = "/metadata/identity/oauth2/token";
615
- const imdsApiVersion = "2018-02-01";
616
- const azureArcAPIVersion = "2019-11-01";
617
- const azureFabricVersion = "2019-07-01-preview";
618
-
619
- // Copyright (c) Microsoft Corporation.
620
- // Licensed under the MIT license.
428
+ const tracingClient = coreTracing.createTracingClient({
429
+ namespace: "Microsoft.AAD",
430
+ packageName: "@azure/identity",
431
+ packageVersion: SDK_VERSION,
432
+ });
433
+
434
+ // Copyright (c) Microsoft Corporation.
435
+ // Licensed under the MIT license.
436
+ const DefaultScopeSuffix = "/.default";
437
+ const imdsHost = "http://169.254.169.254";
438
+ const imdsEndpointPath = "/metadata/identity/oauth2/token";
439
+ const imdsApiVersion = "2018-02-01";
440
+ const azureArcAPIVersion = "2019-11-01";
441
+ const azureFabricVersion = "2019-07-01-preview";
442
+
443
+ // Copyright (c) Microsoft Corporation.
444
+ // Licensed under the MIT license.
621
445
  /**
622
446
  * Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
623
447
  * These are GET requests that require sending a `resource` parameter on the query.
@@ -899,1082 +723,1261 @@ class IdentityClient extends coreClient.ServiceClient {
899
723
 
900
724
  // Copyright (c) Microsoft Corporation.
901
725
  // Licensed under the MIT license.
902
- /**
903
- * Helps specify a regional authority, or "AutoDiscoverRegion" to auto-detect the region.
904
- */
905
- var RegionalAuthority;
906
- (function (RegionalAuthority) {
907
- /** Instructs MSAL to attempt to discover the region */
908
- RegionalAuthority["AutoDiscoverRegion"] = "AutoDiscoverRegion";
909
- /** Uses the {@link RegionalAuthority} for the Azure 'westus' region. */
910
- RegionalAuthority["USWest"] = "westus";
911
- /** Uses the {@link RegionalAuthority} for the Azure 'westus2' region. */
912
- RegionalAuthority["USWest2"] = "westus2";
913
- /** Uses the {@link RegionalAuthority} for the Azure 'centralus' region. */
914
- RegionalAuthority["USCentral"] = "centralus";
915
- /** Uses the {@link RegionalAuthority} for the Azure 'eastus' region. */
916
- RegionalAuthority["USEast"] = "eastus";
917
- /** Uses the {@link RegionalAuthority} for the Azure 'eastus2' region. */
918
- RegionalAuthority["USEast2"] = "eastus2";
919
- /** Uses the {@link RegionalAuthority} for the Azure 'northcentralus' region. */
920
- RegionalAuthority["USNorthCentral"] = "northcentralus";
921
- /** Uses the {@link RegionalAuthority} for the Azure 'southcentralus' region. */
922
- RegionalAuthority["USSouthCentral"] = "southcentralus";
923
- /** Uses the {@link RegionalAuthority} for the Azure 'westcentralus' region. */
924
- RegionalAuthority["USWestCentral"] = "westcentralus";
925
- /** Uses the {@link RegionalAuthority} for the Azure 'canadacentral' region. */
926
- RegionalAuthority["CanadaCentral"] = "canadacentral";
927
- /** Uses the {@link RegionalAuthority} for the Azure 'canadaeast' region. */
928
- RegionalAuthority["CanadaEast"] = "canadaeast";
929
- /** Uses the {@link RegionalAuthority} for the Azure 'brazilsouth' region. */
930
- RegionalAuthority["BrazilSouth"] = "brazilsouth";
931
- /** Uses the {@link RegionalAuthority} for the Azure 'northeurope' region. */
932
- RegionalAuthority["EuropeNorth"] = "northeurope";
933
- /** Uses the {@link RegionalAuthority} for the Azure 'westeurope' region. */
934
- RegionalAuthority["EuropeWest"] = "westeurope";
935
- /** Uses the {@link RegionalAuthority} for the Azure 'uksouth' region. */
936
- RegionalAuthority["UKSouth"] = "uksouth";
937
- /** Uses the {@link RegionalAuthority} for the Azure 'ukwest' region. */
938
- RegionalAuthority["UKWest"] = "ukwest";
939
- /** Uses the {@link RegionalAuthority} for the Azure 'francecentral' region. */
940
- RegionalAuthority["FranceCentral"] = "francecentral";
941
- /** Uses the {@link RegionalAuthority} for the Azure 'francesouth' region. */
942
- RegionalAuthority["FranceSouth"] = "francesouth";
943
- /** Uses the {@link RegionalAuthority} for the Azure 'switzerlandnorth' region. */
944
- RegionalAuthority["SwitzerlandNorth"] = "switzerlandnorth";
945
- /** Uses the {@link RegionalAuthority} for the Azure 'switzerlandwest' region. */
946
- RegionalAuthority["SwitzerlandWest"] = "switzerlandwest";
947
- /** Uses the {@link RegionalAuthority} for the Azure 'germanynorth' region. */
948
- RegionalAuthority["GermanyNorth"] = "germanynorth";
949
- /** Uses the {@link RegionalAuthority} for the Azure 'germanywestcentral' region. */
950
- RegionalAuthority["GermanyWestCentral"] = "germanywestcentral";
951
- /** Uses the {@link RegionalAuthority} for the Azure 'norwaywest' region. */
952
- RegionalAuthority["NorwayWest"] = "norwaywest";
953
- /** Uses the {@link RegionalAuthority} for the Azure 'norwayeast' region. */
954
- RegionalAuthority["NorwayEast"] = "norwayeast";
955
- /** Uses the {@link RegionalAuthority} for the Azure 'eastasia' region. */
956
- RegionalAuthority["AsiaEast"] = "eastasia";
957
- /** Uses the {@link RegionalAuthority} for the Azure 'southeastasia' region. */
958
- RegionalAuthority["AsiaSouthEast"] = "southeastasia";
959
- /** Uses the {@link RegionalAuthority} for the Azure 'japaneast' region. */
960
- RegionalAuthority["JapanEast"] = "japaneast";
961
- /** Uses the {@link RegionalAuthority} for the Azure 'japanwest' region. */
962
- RegionalAuthority["JapanWest"] = "japanwest";
963
- /** Uses the {@link RegionalAuthority} for the Azure 'australiaeast' region. */
964
- RegionalAuthority["AustraliaEast"] = "australiaeast";
965
- /** Uses the {@link RegionalAuthority} for the Azure 'australiasoutheast' region. */
966
- RegionalAuthority["AustraliaSouthEast"] = "australiasoutheast";
967
- /** Uses the {@link RegionalAuthority} for the Azure 'australiacentral' region. */
968
- RegionalAuthority["AustraliaCentral"] = "australiacentral";
969
- /** Uses the {@link RegionalAuthority} for the Azure 'australiacentral2' region. */
970
- RegionalAuthority["AustraliaCentral2"] = "australiacentral2";
971
- /** Uses the {@link RegionalAuthority} for the Azure 'centralindia' region. */
972
- RegionalAuthority["IndiaCentral"] = "centralindia";
973
- /** Uses the {@link RegionalAuthority} for the Azure 'southindia' region. */
974
- RegionalAuthority["IndiaSouth"] = "southindia";
975
- /** Uses the {@link RegionalAuthority} for the Azure 'westindia' region. */
976
- RegionalAuthority["IndiaWest"] = "westindia";
977
- /** Uses the {@link RegionalAuthority} for the Azure 'koreasouth' region. */
978
- RegionalAuthority["KoreaSouth"] = "koreasouth";
979
- /** Uses the {@link RegionalAuthority} for the Azure 'koreacentral' region. */
980
- RegionalAuthority["KoreaCentral"] = "koreacentral";
981
- /** Uses the {@link RegionalAuthority} for the Azure 'uaecentral' region. */
982
- RegionalAuthority["UAECentral"] = "uaecentral";
983
- /** Uses the {@link RegionalAuthority} for the Azure 'uaenorth' region. */
984
- RegionalAuthority["UAENorth"] = "uaenorth";
985
- /** Uses the {@link RegionalAuthority} for the Azure 'southafricanorth' region. */
986
- RegionalAuthority["SouthAfricaNorth"] = "southafricanorth";
987
- /** Uses the {@link RegionalAuthority} for the Azure 'southafricawest' region. */
988
- RegionalAuthority["SouthAfricaWest"] = "southafricawest";
989
- /** Uses the {@link RegionalAuthority} for the Azure 'chinanorth' region. */
990
- RegionalAuthority["ChinaNorth"] = "chinanorth";
991
- /** Uses the {@link RegionalAuthority} for the Azure 'chinaeast' region. */
992
- RegionalAuthority["ChinaEast"] = "chinaeast";
993
- /** Uses the {@link RegionalAuthority} for the Azure 'chinanorth2' region. */
994
- RegionalAuthority["ChinaNorth2"] = "chinanorth2";
995
- /** Uses the {@link RegionalAuthority} for the Azure 'chinaeast2' region. */
996
- RegionalAuthority["ChinaEast2"] = "chinaeast2";
997
- /** Uses the {@link RegionalAuthority} for the Azure 'germanycentral' region. */
998
- RegionalAuthority["GermanyCentral"] = "germanycentral";
999
- /** Uses the {@link RegionalAuthority} for the Azure 'germanynortheast' region. */
1000
- RegionalAuthority["GermanyNorthEast"] = "germanynortheast";
1001
- /** Uses the {@link RegionalAuthority} for the Azure 'usgovvirginia' region. */
1002
- RegionalAuthority["GovernmentUSVirginia"] = "usgovvirginia";
1003
- /** Uses the {@link RegionalAuthority} for the Azure 'usgoviowa' region. */
1004
- RegionalAuthority["GovernmentUSIowa"] = "usgoviowa";
1005
- /** Uses the {@link RegionalAuthority} for the Azure 'usgovarizona' region. */
1006
- RegionalAuthority["GovernmentUSArizona"] = "usgovarizona";
1007
- /** Uses the {@link RegionalAuthority} for the Azure 'usgovtexas' region. */
1008
- RegionalAuthority["GovernmentUSTexas"] = "usgovtexas";
1009
- /** Uses the {@link RegionalAuthority} for the Azure 'usdodeast' region. */
1010
- RegionalAuthority["GovernmentUSDodEast"] = "usdodeast";
1011
- /** Uses the {@link RegionalAuthority} for the Azure 'usdodcentral' region. */
1012
- RegionalAuthority["GovernmentUSDodCentral"] = "usdodcentral";
1013
- })(RegionalAuthority || (RegionalAuthority = {}));
1014
-
1015
- // Copyright (c) Microsoft Corporation.
1016
- // Licensed under the MIT license.
1017
- /**
1018
- * The current persistence provider, undefined by default.
1019
- * @internal
1020
- */
1021
- let persistenceProvider = undefined;
1022
- /**
1023
- * An object that allows setting the persistence provider.
1024
- * @internal
1025
- */
1026
- const msalNodeFlowCacheControl = {
1027
- setPersistence(pluginProvider) {
1028
- persistenceProvider = pluginProvider;
726
+ const CommonTenantId = "common";
727
+ const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'
728
+ const logger$o = credentialLogger("VisualStudioCodeCredential");
729
+ let findCredentials = undefined;
730
+ const vsCodeCredentialControl = {
731
+ setVsCodeCredentialFinder(finder) {
732
+ findCredentials = finder;
1029
733
  },
1030
734
  };
1031
- /**
1032
- * The current native broker provider, undefined by default.
1033
- * @internal
1034
- */
1035
- let nativeBrokerInfo = undefined;
1036
- function hasNativeBroker() {
1037
- return nativeBrokerInfo !== undefined;
735
+ // Map of unsupported Tenant IDs and the errors we will be throwing.
736
+ const unsupportedTenantIds = {
737
+ adfs: "The VisualStudioCodeCredential does not support authentication with ADFS tenants.",
738
+ };
739
+ function checkUnsupportedTenant(tenantId) {
740
+ // If the Tenant ID isn't supported, we throw.
741
+ const unsupportedTenantError = unsupportedTenantIds[tenantId];
742
+ if (unsupportedTenantError) {
743
+ throw new CredentialUnavailableError(unsupportedTenantError);
744
+ }
1038
745
  }
746
+ const mapVSCodeAuthorityHosts = {
747
+ AzureCloud: exports.AzureAuthorityHosts.AzurePublicCloud,
748
+ AzureChina: exports.AzureAuthorityHosts.AzureChina,
749
+ AzureGermanCloud: exports.AzureAuthorityHosts.AzureGermany,
750
+ AzureUSGovernment: exports.AzureAuthorityHosts.AzureGovernment,
751
+ };
1039
752
  /**
1040
- * An object that allows setting the native broker provider.
1041
- * @internal
753
+ * Attempts to load a specific property from the VSCode configurations of the current OS.
754
+ * If it fails at any point, returns undefined.
1042
755
  */
1043
- const msalNodeFlowNativeBrokerControl = {
1044
- setNativeBroker(broker) {
1045
- nativeBrokerInfo = {
1046
- broker,
1047
- };
1048
- },
1049
- };
756
+ function getPropertyFromVSCode(property) {
757
+ const settingsPath = ["User", "settings.json"];
758
+ // Eventually we can add more folders for more versions of VSCode.
759
+ const vsCodeFolder = "Code";
760
+ const homedir = os.homedir();
761
+ function loadProperty(...pathSegments) {
762
+ const fullPath = path.join(...pathSegments, vsCodeFolder, ...settingsPath);
763
+ const settings = JSON.parse(fs.readFileSync(fullPath, { encoding: "utf8" }));
764
+ return settings[property];
765
+ }
766
+ try {
767
+ let appData;
768
+ switch (process.platform) {
769
+ case "win32":
770
+ appData = process.env.APPDATA;
771
+ return appData ? loadProperty(appData) : undefined;
772
+ case "darwin":
773
+ return loadProperty(homedir, "Library", "Application Support");
774
+ case "linux":
775
+ return loadProperty(homedir, ".config");
776
+ default:
777
+ return;
778
+ }
779
+ }
780
+ catch (e) {
781
+ logger$o.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);
782
+ return;
783
+ }
784
+ }
1050
785
  /**
1051
- * MSAL partial base client for Node.js.
1052
- *
1053
- * It completes the input configuration with some default values.
1054
- * It also provides with utility protected methods that can be used from any of the clients,
1055
- * which includes handlers for successful responses and errors.
786
+ * Connects to Azure using the credential provided by the VSCode extension 'Azure Account'.
787
+ * Once the user has logged in via the extension, this credential can share the same refresh token
788
+ * that is cached by the extension.
1056
789
  *
1057
- * @internal
790
+ * It's a [known issue](https://github.com/Azure/azure-sdk-for-js/issues/20500) that this credential doesn't
791
+ * work with [Azure Account extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account)
792
+ * versions newer than **0.9.11**. A long-term fix to this problem is in progress. In the meantime, consider
793
+ * authenticating with {@link AzureCliCredential}.
1058
794
  */
1059
- class MsalNode {
795
+ class VisualStudioCodeCredential {
796
+ /**
797
+ * Creates an instance of VisualStudioCodeCredential to use for automatically authenticating via VSCode.
798
+ *
799
+ * **Note**: `VisualStudioCodeCredential` is provided by a plugin package:
800
+ * `@azure/identity-vscode`. If this package is not installed and registered
801
+ * using the plugin API (`useIdentityPlugin`), then authentication using
802
+ * `VisualStudioCodeCredential` will not be available.
803
+ *
804
+ * @param options - Options for configuring the client which makes the authentication request.
805
+ */
1060
806
  constructor(options) {
1061
- var _a, _b, _c, _d, _e, _f, _g;
1062
- this.app = {};
1063
- this.caeApp = {};
1064
- this.requiresConfidential = false;
1065
- this.logger = options.logger;
1066
- this.msalConfig = this.defaultNodeMsalConfig(options);
1067
- this.tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
1068
- this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
1069
- this.clientId = this.msalConfig.auth.clientId;
1070
- if (options === null || options === void 0 ? void 0 : options.getAssertion) {
1071
- this.getAssertion = options.getAssertion;
1072
- }
1073
- this.enableBroker = (_b = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _b === void 0 ? void 0 : _b.enabled;
1074
- this.enableMsaPassthrough = (_c = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough;
1075
- this.parentWindowHandle = (_d = options.brokerOptions) === null || _d === void 0 ? void 0 : _d.parentWindowHandle;
1076
- // If persistence has been configured
1077
- if (persistenceProvider !== undefined && ((_e = options.tokenCachePersistenceOptions) === null || _e === void 0 ? void 0 : _e.enabled)) {
1078
- const nonCaeOptions = Object.assign({ name: `${options.tokenCachePersistenceOptions.name}.${CACHE_NON_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
1079
- const caeOptions = Object.assign({ name: `${options.tokenCachePersistenceOptions.name}.${CACHE_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
1080
- this.createCachePlugin = () => persistenceProvider(nonCaeOptions);
1081
- this.createCachePluginCae = () => persistenceProvider(caeOptions);
1082
- }
1083
- else if ((_f = options.tokenCachePersistenceOptions) === null || _f === void 0 ? void 0 : _f.enabled) {
1084
- throw new Error([
1085
- "Persistent token caching was requested, but no persistence provider was configured.",
1086
- "You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)",
1087
- "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
1088
- "`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`.",
1089
- ].join(" "));
1090
- }
1091
- // If broker has not been configured
1092
- if (!hasNativeBroker() && this.enableBroker) {
1093
- throw new Error([
1094
- "Broker for WAM was requested to be enabled, but no native broker was configured.",
1095
- "You must install the identity-broker plugin package (`npm install --save @azure/identity-broker`)",
1096
- "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
1097
- "`useIdentityPlugin(createNativeBrokerPlugin())` before using `enableBroker`.",
1098
- ].join(" "));
807
+ // We want to make sure we use the one assigned by the user on the VSCode settings.
808
+ // Or just `AzureCloud` by default.
809
+ this.cloudName = (getPropertyFromVSCode("azure.cloud") || "AzureCloud");
810
+ // Picking an authority host based on the cloud name.
811
+ const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];
812
+ this.identityClient = new IdentityClient(Object.assign({ authorityHost }, options));
813
+ if (options && options.tenantId) {
814
+ checkTenantId(logger$o, options.tenantId);
815
+ this.tenantId = options.tenantId;
1099
816
  }
1100
- this.azureRegion = (_g = options.regionalAuthority) !== null && _g !== void 0 ? _g : process.env.AZURE_REGIONAL_AUTHORITY_NAME;
1101
- if (this.azureRegion === RegionalAuthority.AutoDiscoverRegion) {
1102
- this.azureRegion = "AUTO_DISCOVER";
817
+ else {
818
+ this.tenantId = CommonTenantId;
1103
819
  }
820
+ this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
821
+ checkUnsupportedTenant(this.tenantId);
1104
822
  }
1105
823
  /**
1106
- * Generates a MSAL configuration that generally works for Node.js
824
+ * Runs preparations for any further getToken request.
1107
825
  */
1108
- defaultNodeMsalConfig(options) {
1109
- var _a;
1110
- const clientId = options.clientId || DeveloperSignOnClientId;
1111
- const tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
1112
- this.authorityHost = options.authorityHost || process.env.AZURE_AUTHORITY_HOST;
1113
- const authority = getAuthority(tenantId, this.authorityHost);
1114
- this.identityClient = new IdentityClient(Object.assign(Object.assign({}, options.tokenCredentialOptions), { authorityHost: authority, loggingOptions: options.loggingOptions }));
1115
- const clientCapabilities = [];
1116
- return {
1117
- auth: {
1118
- clientId,
1119
- authority,
1120
- knownAuthorities: getKnownAuthorities(tenantId, authority, options.disableInstanceDiscovery),
1121
- clientCapabilities,
1122
- },
1123
- // Cache is defined in this.prepare();
1124
- system: {
1125
- networkClient: this.identityClient,
1126
- loggerOptions: {
1127
- loggerCallback: defaultLoggerCallback(options.logger),
1128
- logLevel: getMSALLogLevel(logger$q.getLogLevel()),
1129
- piiLoggingEnabled: (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.enableUnsafeSupportLogging,
1130
- },
1131
- },
1132
- };
1133
- }
1134
- getApp(appType, enableCae) {
1135
- const app = enableCae ? this.caeApp : this.app;
1136
- if (appType === "publicFirst") {
1137
- return (app.public || app.confidential);
1138
- }
1139
- else if (appType === "confidentialFirst") {
1140
- return (app.confidential || app.public);
1141
- }
1142
- else if (appType === "confidential") {
1143
- return app.confidential;
1144
- }
1145
- else {
1146
- return app.public;
826
+ async prepare() {
827
+ // Attempts to load the tenant from the VSCode configuration file.
828
+ const settingsTenant = getPropertyFromVSCode("azure.tenant");
829
+ if (settingsTenant) {
830
+ this.tenantId = settingsTenant;
1147
831
  }
832
+ checkUnsupportedTenant(this.tenantId);
1148
833
  }
1149
834
  /**
1150
- * Prepares the MSAL applications.
835
+ * Runs preparations for any further getToken, but only once.
1151
836
  */
1152
- async init(options) {
1153
- if (options === null || options === void 0 ? void 0 : options.abortSignal) {
1154
- options.abortSignal.addEventListener("abort", () => {
1155
- // This will abort any pending request in the IdentityClient,
1156
- // based on the received or generated correlationId
1157
- this.identityClient.abortRequests(options.correlationId);
1158
- });
1159
- }
1160
- const app = (options === null || options === void 0 ? void 0 : options.enableCae) ? this.caeApp : this.app;
1161
- if (options === null || options === void 0 ? void 0 : options.enableCae) {
1162
- this.msalConfig.auth.clientCapabilities = ["cp1"];
837
+ prepareOnce() {
838
+ if (!this.preparePromise) {
839
+ this.preparePromise = this.prepare();
1163
840
  }
1164
- if (app.public || app.confidential) {
1165
- return;
841
+ return this.preparePromise;
842
+ }
843
+ /**
844
+ * Returns the token found by searching VSCode's authentication cache or
845
+ * returns null if no token could be found.
846
+ *
847
+ * @param scopes - The list of scopes for which the token will have access.
848
+ * @param options - The options used to configure any requests this
849
+ * `TokenCredential` implementation might make.
850
+ */
851
+ async getToken(scopes, options) {
852
+ var _a, _b;
853
+ await this.prepareOnce();
854
+ const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds, logger$o) || this.tenantId;
855
+ if (findCredentials === undefined) {
856
+ throw new CredentialUnavailableError([
857
+ "No implementation of `VisualStudioCodeCredential` is available.",
858
+ "You must install the identity-vscode plugin package (`npm install --save-dev @azure/identity-vscode`)",
859
+ "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
860
+ "`useIdentityPlugin(vsCodePlugin)` before creating a `VisualStudioCodeCredential`.",
861
+ "To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.",
862
+ ].join(" "));
1166
863
  }
1167
- if ((options === null || options === void 0 ? void 0 : options.enableCae) && this.createCachePluginCae !== undefined) {
1168
- this.msalConfig.cache = {
1169
- cachePlugin: await this.createCachePluginCae(),
1170
- };
864
+ let scopeString = typeof scopes === "string" ? scopes : scopes.join(" ");
865
+ // Check to make sure the scope we get back is a valid scope
866
+ if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {
867
+ const error = new Error("Invalid scope was specified by the user or calling client");
868
+ logger$o.getToken.info(formatError(scopes, error));
869
+ throw error;
1171
870
  }
1172
- if (this.createCachePlugin !== undefined) {
1173
- this.msalConfig.cache = {
1174
- cachePlugin: await this.createCachePlugin(),
1175
- };
871
+ if (scopeString.indexOf("offline_access") < 0) {
872
+ scopeString += " offline_access";
1176
873
  }
1177
- if (hasNativeBroker() && this.enableBroker) {
1178
- this.msalConfig.broker = {
1179
- nativeBrokerPlugin: nativeBrokerInfo.broker,
1180
- };
1181
- if (!this.parentWindowHandle) {
1182
- // error should have been thrown from within the constructor of InteractiveBrowserCredential
1183
- this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
874
+ // findCredentials returns an array similar to:
875
+ // [
876
+ // {
877
+ // account: "",
878
+ // password: "",
879
+ // },
880
+ // /* ... */
881
+ // ]
882
+ const credentials = await findCredentials();
883
+ // If we can't find the credential based on the name, we'll pick the first one available.
884
+ const { password: refreshToken } = (_b = (_a = credentials.find(({ account }) => account === this.cloudName)) !== null && _a !== void 0 ? _a : credentials[0]) !== null && _b !== void 0 ? _b : {};
885
+ if (refreshToken) {
886
+ const tokenResponse = await this.identityClient.refreshAccessToken(tenantId, AzureAccountClientId, scopeString, refreshToken, undefined);
887
+ if (tokenResponse) {
888
+ logger$o.getToken.info(formatSuccess(scopes));
889
+ return tokenResponse.accessToken;
890
+ }
891
+ else {
892
+ const error = new CredentialUnavailableError("Could not retrieve the token associated with Visual Studio Code. Have you connected using the 'Azure Account' extension recently? To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.");
893
+ logger$o.getToken.info(formatError(scopes, error));
894
+ throw error;
1184
895
  }
1185
- }
1186
- if (options === null || options === void 0 ? void 0 : options.enableCae) {
1187
- this.caeApp.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
1188
896
  }
1189
897
  else {
1190
- this.app.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
898
+ const error = new CredentialUnavailableError("Could not retrieve the token associated with Visual Studio Code. Did you connect using the 'Azure Account' extension? To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.");
899
+ logger$o.getToken.info(formatError(scopes, error));
900
+ throw error;
1191
901
  }
1192
- if (this.getAssertion) {
1193
- this.msalConfig.auth.clientAssertion = await this.getAssertion();
902
+ }
903
+ }
904
+
905
+ // Copyright (c) Microsoft Corporation.
906
+ // Licensed under the MIT license.
907
+ /**
908
+ * The context passed to an Identity plugin. This contains objects that
909
+ * plugins can use to set backend implementations.
910
+ * @internal
911
+ */
912
+ const pluginContext = {
913
+ cachePluginControl: msalNodeFlowCacheControl,
914
+ nativeBrokerPluginControl: msalNodeFlowNativeBrokerControl,
915
+ vsCodeCredentialControl: vsCodeCredentialControl,
916
+ };
917
+ /**
918
+ * Extend Azure Identity with additional functionality. Pass a plugin from
919
+ * a plugin package, such as:
920
+ *
921
+ * - `@azure/identity-cache-persistence`: provides persistent token caching
922
+ * - `@azure/identity-vscode`: provides the dependencies of
923
+ * `VisualStudioCodeCredential` and enables it
924
+ *
925
+ * Example:
926
+ *
927
+ * ```javascript
928
+ * import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
929
+ *
930
+ * import { useIdentityPlugin, DefaultAzureCredential } from "@azure/identity";
931
+ * useIdentityPlugin(cachePersistencePlugin);
932
+ *
933
+ * // The plugin has the capability to extend `DefaultAzureCredential` and to
934
+ * // add middleware to the underlying credentials, such as persistence.
935
+ * const credential = new DefaultAzureCredential({
936
+ * tokenCachePersistenceOptions: {
937
+ * enabled: true
938
+ * }
939
+ * });
940
+ * ```
941
+ *
942
+ * @param plugin - the plugin to register
943
+ */
944
+ function useIdentityPlugin(plugin) {
945
+ plugin(pluginContext);
946
+ }
947
+
948
+ // Copyright (c) Microsoft Corporation.
949
+ // Licensed under the MIT license.
950
+ const msiName$6 = "ManagedIdentityCredential - AppServiceMSI 2017";
951
+ const logger$n = credentialLogger(msiName$6);
952
+ /**
953
+ * Generates the options used on the request for an access token.
954
+ */
955
+ function prepareRequestOptions$5(scopes, clientId) {
956
+ const resource = mapScopesToResource(scopes);
957
+ if (!resource) {
958
+ throw new Error(`${msiName$6}: Multiple scopes are not supported.`);
959
+ }
960
+ const queryParameters = {
961
+ resource,
962
+ "api-version": "2017-09-01",
963
+ };
964
+ if (clientId) {
965
+ queryParameters.clientid = clientId;
966
+ }
967
+ const query = new URLSearchParams(queryParameters);
968
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
969
+ if (!process.env.MSI_ENDPOINT) {
970
+ throw new Error(`${msiName$6}: Missing environment variable: MSI_ENDPOINT`);
971
+ }
972
+ if (!process.env.MSI_SECRET) {
973
+ throw new Error(`${msiName$6}: Missing environment variable: MSI_SECRET`);
974
+ }
975
+ return {
976
+ url: `${process.env.MSI_ENDPOINT}?${query.toString()}`,
977
+ method: "GET",
978
+ headers: coreRestPipeline.createHttpHeaders({
979
+ Accept: "application/json",
980
+ secret: process.env.MSI_SECRET,
981
+ }),
982
+ };
983
+ }
984
+ /**
985
+ * Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
986
+ */
987
+ const appServiceMsi2017 = {
988
+ name: "appServiceMsi2017",
989
+ async isAvailable({ scopes }) {
990
+ const resource = mapScopesToResource(scopes);
991
+ if (!resource) {
992
+ logger$n.info(`${msiName$6}: Unavailable. Multiple scopes are not supported.`);
993
+ return false;
1194
994
  }
1195
- // The confidential client requires either a secret, assertion or certificate.
1196
- if (this.msalConfig.auth.clientSecret ||
1197
- this.msalConfig.auth.clientAssertion ||
1198
- this.msalConfig.auth.clientCertificate) {
1199
- if (options === null || options === void 0 ? void 0 : options.enableCae) {
1200
- this.caeApp.confidential = new msalCommon__namespace.ConfidentialClientApplication(this.msalConfig);
1201
- }
1202
- else {
1203
- this.app.confidential = new msalCommon__namespace.ConfidentialClientApplication(this.msalConfig);
1204
- }
995
+ const env = process.env;
996
+ const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
997
+ if (!result) {
998
+ logger$n.info(`${msiName$6}: Unavailable. The environment variables needed are: MSI_ENDPOINT and MSI_SECRET.`);
1205
999
  }
1206
- else {
1207
- if (this.requiresConfidential) {
1208
- throw new Error("Unable to generate the MSAL confidential client. Missing either the client's secret, certificate or assertion.");
1209
- }
1000
+ return result;
1001
+ },
1002
+ async getToken(configuration, getTokenOptions = {}) {
1003
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1004
+ if (resourceId) {
1005
+ logger$n.warning(`${msiName$6}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
1210
1006
  }
1007
+ logger$n.info(`${msiName$6}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
1008
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId)), {
1009
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1010
+ allowInsecureConnection: true }));
1011
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1012
+ return (tokenResponse && tokenResponse.accessToken) || null;
1013
+ },
1014
+ };
1015
+
1016
+ // Copyright (c) Microsoft Corporation.
1017
+ // Licensed under the MIT license.
1018
+ const msiName$5 = "ManagedIdentityCredential - CloudShellMSI";
1019
+ const logger$m = credentialLogger(msiName$5);
1020
+ /**
1021
+ * Generates the options used on the request for an access token.
1022
+ */
1023
+ function prepareRequestOptions$4(scopes, clientId, resourceId) {
1024
+ const resource = mapScopesToResource(scopes);
1025
+ if (!resource) {
1026
+ throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
1211
1027
  }
1212
- /**
1213
- * Allows the cancellation of a MSAL request.
1214
- */
1215
- withCancellation(promise, abortSignal, onCancel) {
1216
- return new Promise((resolve, reject) => {
1217
- promise
1218
- .then((msalToken) => {
1219
- return resolve(msalToken);
1220
- })
1221
- .catch(reject);
1222
- if (abortSignal) {
1223
- abortSignal.addEventListener("abort", () => {
1224
- onCancel === null || onCancel === void 0 ? void 0 : onCancel();
1225
- });
1226
- }
1227
- });
1028
+ const body = {
1029
+ resource,
1030
+ };
1031
+ if (clientId) {
1032
+ body.client_id = clientId;
1228
1033
  }
1229
- /**
1230
- * Returns the existing account, attempts to load the account from MSAL.
1231
- */
1232
- async getActiveAccount(enableCae = false) {
1233
- if (this.account) {
1234
- return this.account;
1034
+ if (resourceId) {
1035
+ body.msi_res_id = resourceId;
1036
+ }
1037
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1038
+ if (!process.env.MSI_ENDPOINT) {
1039
+ throw new Error(`${msiName$5}: Missing environment variable: MSI_ENDPOINT`);
1040
+ }
1041
+ const params = new URLSearchParams(body);
1042
+ return {
1043
+ url: process.env.MSI_ENDPOINT,
1044
+ method: "POST",
1045
+ body: params.toString(),
1046
+ headers: coreRestPipeline.createHttpHeaders({
1047
+ Accept: "application/json",
1048
+ Metadata: "true",
1049
+ "Content-Type": "application/x-www-form-urlencoded",
1050
+ }),
1051
+ };
1052
+ }
1053
+ /**
1054
+ * Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
1055
+ * Since Azure Managed Identities aren't available in the Azure Cloud Shell, we log a warning for users that try to access cloud shell using user assigned identity.
1056
+ */
1057
+ const cloudShellMsi = {
1058
+ name: "cloudShellMsi",
1059
+ async isAvailable({ scopes }) {
1060
+ const resource = mapScopesToResource(scopes);
1061
+ if (!resource) {
1062
+ logger$m.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
1063
+ return false;
1235
1064
  }
1236
- const cache = this.getApp("confidentialFirst", enableCae).getTokenCache();
1237
- const accountsByTenant = await (cache === null || cache === void 0 ? void 0 : cache.getAllAccounts());
1238
- if (!accountsByTenant) {
1239
- return;
1065
+ const result = Boolean(process.env.MSI_ENDPOINT);
1066
+ if (!result) {
1067
+ logger$m.info(`${msiName$5}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
1240
1068
  }
1241
- if (accountsByTenant.length === 1) {
1242
- this.account = msalToPublic(this.clientId, accountsByTenant[0]);
1069
+ return result;
1070
+ },
1071
+ async getToken(configuration, getTokenOptions = {}) {
1072
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1073
+ if (clientId) {
1074
+ logger$m.warning(`${msiName$5}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1243
1075
  }
1244
- else {
1245
- this.logger
1246
- .info(`More than one account was found authenticated for this Client ID and Tenant ID.
1247
- However, no "authenticationRecord" has been provided for this credential,
1248
- therefore we're unable to pick between these accounts.
1249
- A new login attempt will be requested, to ensure the correct account is picked.
1250
- To work with multiple accounts for the same Client ID and Tenant ID, please provide an "authenticationRecord" when initializing a credential to prevent this from happening.`);
1251
- return;
1076
+ if (resourceId) {
1077
+ logger$m.warning(`${msiName$5}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
1252
1078
  }
1253
- return this.account;
1079
+ logger$m.info(`${msiName$5}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
1080
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
1081
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1082
+ allowInsecureConnection: true }));
1083
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1084
+ return (tokenResponse && tokenResponse.accessToken) || null;
1085
+ },
1086
+ };
1087
+
1088
+ // Copyright (c) Microsoft Corporation.
1089
+ // Licensed under the MIT license.
1090
+ const msiName$4 = "ManagedIdentityCredential - IMDS";
1091
+ const logger$l = credentialLogger(msiName$4);
1092
+ /**
1093
+ * Generates the options used on the request for an access token.
1094
+ */
1095
+ function prepareRequestOptions$3(scopes, clientId, resourceId, options) {
1096
+ var _a;
1097
+ const resource = mapScopesToResource(scopes);
1098
+ if (!resource) {
1099
+ throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
1254
1100
  }
1255
- /**
1256
- * Attempts to retrieve a token from cache.
1257
- */
1258
- async getTokenSilent(scopes, options) {
1259
- var _a, _b, _c;
1260
- await this.getActiveAccount(options === null || options === void 0 ? void 0 : options.enableCae);
1261
- if (!this.account) {
1262
- throw new AuthenticationRequiredError({
1263
- scopes,
1264
- getTokenOptions: options,
1265
- message: "Silent authentication failed. We couldn't retrieve an active account from the cache.",
1266
- });
1267
- }
1268
- const silentRequest = {
1269
- // To be able to re-use the account, the Token Cache must also have been provided.
1270
- account: publicToMsal(this.account),
1271
- correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
1272
- scopes,
1273
- authority: options === null || options === void 0 ? void 0 : options.authority,
1274
- claims: options === null || options === void 0 ? void 0 : options.claims,
1101
+ const { skipQuery, skipMetadataHeader } = options || {};
1102
+ let query = "";
1103
+ // Pod Identity will try to process this request even if the Metadata header is missing.
1104
+ // We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
1105
+ if (!skipQuery) {
1106
+ const queryParameters = {
1107
+ resource,
1108
+ "api-version": imdsApiVersion,
1275
1109
  };
1276
- if (hasNativeBroker() && this.enableBroker) {
1277
- if (!silentRequest.tokenQueryParameters) {
1278
- silentRequest.tokenQueryParameters = {};
1279
- }
1280
- if (!this.parentWindowHandle) {
1281
- // error should have been thrown from within the constructor of InteractiveBrowserCredential
1282
- this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
1283
- }
1284
- if (this.enableMsaPassthrough) {
1285
- silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
1286
- }
1287
- }
1288
- try {
1289
- this.logger.info("Attempting to acquire token silently");
1290
- /**
1291
- * The following code to retrieve all accounts is done as a workaround in an attempt to force the
1292
- * refresh of the token cache with the token and the account passed in through the
1293
- * `authenticationRecord` parameter. See issue - https://github.com/Azure/azure-sdk-for-js/issues/24349#issuecomment-1496715651
1294
- * This workaround serves as a workaround for silent authentication not happening when authenticationRecord is passed.
1295
- */
1296
- await ((_a = this.getApp("publicFirst", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _a === void 0 ? void 0 : _a.getTokenCache().getAllAccounts());
1297
- const response = (_c = (await ((_b = this.getApp("confidential", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _b === void 0 ? void 0 : _b.acquireTokenSilent(silentRequest)))) !== null && _c !== void 0 ? _c : (await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenSilent(silentRequest));
1298
- return this.handleResult(scopes, response || undefined);
1110
+ if (clientId) {
1111
+ queryParameters.client_id = clientId;
1299
1112
  }
1300
- catch (err) {
1301
- throw handleMsalError(scopes, err, options);
1113
+ if (resourceId) {
1114
+ queryParameters.msi_res_id = resourceId;
1302
1115
  }
1116
+ const params = new URLSearchParams(queryParameters);
1117
+ query = `?${params.toString()}`;
1303
1118
  }
1304
- /**
1305
- * Wrapper around each MSAL flow get token operation: doGetToken.
1306
- * If disableAutomaticAuthentication is sent through the constructor, it will prevent MSAL from requesting the user input.
1307
- */
1308
- async getToken(scopes, options = {}) {
1309
- const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds) ||
1310
- this.tenantId;
1311
- options.authority = getAuthority(tenantId, this.authorityHost);
1312
- options.correlationId = (options === null || options === void 0 ? void 0 : options.correlationId) || randomUUID();
1313
- await this.init(options);
1314
- try {
1315
- // MSAL now caches tokens based on their claims,
1316
- // so now one has to keep track fo claims in order to retrieve the newer tokens from acquireTokenSilent
1317
- // This update happened on PR: https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/4533
1318
- const optionsClaims = options.claims;
1319
- if (optionsClaims) {
1320
- this.cachedClaims = optionsClaims;
1119
+ const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
1120
+ const rawHeaders = {
1121
+ Accept: "application/json",
1122
+ Metadata: "true",
1123
+ };
1124
+ // Remove the Metadata header to invoke a request error from some IMDS endpoints.
1125
+ if (skipMetadataHeader) {
1126
+ delete rawHeaders.Metadata;
1127
+ }
1128
+ return {
1129
+ // In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
1130
+ url: `${url}${query}`,
1131
+ method: "GET",
1132
+ headers: coreRestPipeline.createHttpHeaders(rawHeaders),
1133
+ };
1134
+ }
1135
+ // 800ms -> 1600ms -> 3200ms
1136
+ const imdsMsiRetryConfig = {
1137
+ maxRetries: 3,
1138
+ startDelayInMs: 800,
1139
+ intervalIncrement: 2,
1140
+ };
1141
+ /**
1142
+ * Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
1143
+ */
1144
+ const imdsMsi = {
1145
+ name: "imdsMsi",
1146
+ async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
1147
+ const resource = mapScopesToResource(scopes);
1148
+ if (!resource) {
1149
+ logger$l.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
1150
+ return false;
1151
+ }
1152
+ // if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
1153
+ if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1154
+ return true;
1155
+ }
1156
+ if (!identityClient) {
1157
+ throw new Error("Missing IdentityClient");
1158
+ }
1159
+ const requestOptions = prepareRequestOptions$3(resource, clientId, resourceId, {
1160
+ skipMetadataHeader: true,
1161
+ skipQuery: true,
1162
+ });
1163
+ return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
1164
+ var _a, _b;
1165
+ requestOptions.tracingOptions = options.tracingOptions;
1166
+ // Create a request with a timeout since we expect that
1167
+ // not having a "Metadata" header should cause an error to be
1168
+ // returned quickly from the endpoint, proving its availability.
1169
+ const request = coreRestPipeline.createPipelineRequest(requestOptions);
1170
+ // Default to 1000 if the default of 0 is used.
1171
+ // Negative values can still be used to disable the timeout.
1172
+ request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
1173
+ // This MSI uses the imdsEndpoint to get the token, which only uses http://
1174
+ request.allowInsecureConnection = true;
1175
+ let response;
1176
+ try {
1177
+ logger$l.info(`${msiName$4}: Pinging the Azure IMDS endpoint`);
1178
+ response = await identityClient.sendRequest(request);
1321
1179
  }
1322
- if (this.cachedClaims && !optionsClaims) {
1323
- options.claims = this.cachedClaims;
1180
+ catch (err) {
1181
+ // If the request failed, or Node.js was unable to establish a connection,
1182
+ // or the host was down, we'll assume the IMDS endpoint isn't available.
1183
+ if (coreUtil.isError(err)) {
1184
+ logger$l.verbose(`${msiName$4}: Caught error ${err.name}: ${err.message}`);
1185
+ }
1186
+ // This is a special case for Docker Desktop which responds with a 403 with a message that contains "A socket operation was attempted to an unreachable network"
1187
+ // rather than just timing out, as expected.
1188
+ logger$l.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
1189
+ return false;
1324
1190
  }
1325
- // We don't return the promise since we want to catch errors right here.
1326
- return await this.getTokenSilent(scopes, options);
1191
+ if (response.status === 403) {
1192
+ if ((_b = response.bodyAsText) === null || _b === void 0 ? void 0 : _b.includes("A socket operation was attempted to an unreachable network")) {
1193
+ logger$l.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
1194
+ logger$l.info(`${msiName$4}: ${response.bodyAsText}`);
1195
+ return false;
1196
+ }
1197
+ }
1198
+ // If we received any response, the endpoint is available
1199
+ logger$l.info(`${msiName$4}: The Azure IMDS endpoint is available`);
1200
+ return true;
1201
+ });
1202
+ },
1203
+ async getToken(configuration, getTokenOptions = {}) {
1204
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1205
+ if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1206
+ logger$l.info(`${msiName$4}: Using the Azure IMDS endpoint coming from the environment variable AZURE_POD_IDENTITY_AUTHORITY_HOST=${process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST}.`);
1327
1207
  }
1328
- catch (err) {
1329
- if (err.name !== "AuthenticationRequiredError") {
1330
- throw err;
1208
+ else {
1209
+ logger$l.info(`${msiName$4}: Using the default Azure IMDS endpoint ${imdsHost}.`);
1210
+ }
1211
+ let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
1212
+ for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
1213
+ try {
1214
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
1215
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1216
+ return (tokenResponse && tokenResponse.accessToken) || null;
1331
1217
  }
1332
- if (options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication) {
1333
- throw new AuthenticationRequiredError({
1334
- scopes,
1335
- getTokenOptions: options,
1336
- message: "Automatic authentication has been disabled. You may call the authentication() method.",
1337
- });
1218
+ catch (error) {
1219
+ if (error.statusCode === 404) {
1220
+ await coreUtil.delay(nextDelayInMs);
1221
+ nextDelayInMs *= imdsMsiRetryConfig.intervalIncrement;
1222
+ continue;
1223
+ }
1224
+ throw error;
1338
1225
  }
1339
- this.logger.info(`Silent authentication failed, falling back to interactive method.`);
1340
- return this.doGetToken(scopes, options);
1341
1226
  }
1227
+ throw new AuthenticationError(404, `${msiName$4}: Failed to retrieve IMDS token after ${imdsMsiRetryConfig.maxRetries} retries.`);
1228
+ },
1229
+ };
1230
+
1231
+ // Copyright (c) Microsoft Corporation.
1232
+ // Licensed under the MIT license.
1233
+ const msiName$3 = "ManagedIdentityCredential - Azure Arc MSI";
1234
+ const logger$k = credentialLogger(msiName$3);
1235
+ /**
1236
+ * Generates the options used on the request for an access token.
1237
+ */
1238
+ function prepareRequestOptions$2(scopes, clientId, resourceId) {
1239
+ const resource = mapScopesToResource(scopes);
1240
+ if (!resource) {
1241
+ throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
1342
1242
  }
1343
- /**
1344
- * Handles the MSAL authentication result.
1345
- * If the result has an account, we update the local account reference.
1346
- * If the token received is invalid, an error will be thrown depending on what's missing.
1347
- */
1348
- handleResult(scopes, result, getTokenOptions) {
1349
- if (result === null || result === void 0 ? void 0 : result.account) {
1350
- this.account = msalToPublic(this.clientId, result.account);
1243
+ const queryParameters = {
1244
+ resource,
1245
+ "api-version": azureArcAPIVersion,
1246
+ };
1247
+ if (clientId) {
1248
+ queryParameters.client_id = clientId;
1249
+ }
1250
+ if (resourceId) {
1251
+ queryParameters.msi_res_id = resourceId;
1252
+ }
1253
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1254
+ if (!process.env.IDENTITY_ENDPOINT) {
1255
+ throw new Error(`${msiName$3}: Missing environment variable: IDENTITY_ENDPOINT`);
1256
+ }
1257
+ const query = new URLSearchParams(queryParameters);
1258
+ return coreRestPipeline.createPipelineRequest({
1259
+ // Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
1260
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
1261
+ method: "GET",
1262
+ headers: coreRestPipeline.createHttpHeaders({
1263
+ Accept: "application/json",
1264
+ Metadata: "true",
1265
+ }),
1266
+ });
1267
+ }
1268
+ /**
1269
+ * Retrieves the file contents at the given path using promises.
1270
+ * Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
1271
+ */
1272
+ function readFileAsync$1(path, options) {
1273
+ return new Promise((resolve, reject) => fs.readFile(path, options, (err, data) => {
1274
+ if (err) {
1275
+ reject(err);
1351
1276
  }
1352
- ensureValidMsalToken(scopes, result, getTokenOptions);
1353
- this.logger.getToken.info(formatSuccess(scopes));
1354
- return {
1355
- token: result.accessToken,
1356
- expiresOnTimestamp: result.expiresOn.getTime(),
1357
- };
1277
+ resolve(data);
1278
+ }));
1279
+ }
1280
+ /**
1281
+ * Does a request to the authentication provider that results in a file path.
1282
+ */
1283
+ async function filePathRequest(identityClient, requestPrepareOptions) {
1284
+ const response = await identityClient.sendRequest(coreRestPipeline.createPipelineRequest(requestPrepareOptions));
1285
+ if (response.status !== 401) {
1286
+ let message = "";
1287
+ if (response.bodyAsText) {
1288
+ message = ` Response: ${response.bodyAsText}`;
1289
+ }
1290
+ throw new AuthenticationError(response.status, `${msiName$3}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
1291
+ }
1292
+ const authHeader = response.headers.get("www-authenticate") || "";
1293
+ try {
1294
+ return authHeader.split("=").slice(1)[0];
1295
+ }
1296
+ catch (e) {
1297
+ throw Error(`Invalid www-authenticate header format: ${authHeader}`);
1358
1298
  }
1359
1299
  }
1300
+ /**
1301
+ * Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
1302
+ */
1303
+ const arcMsi = {
1304
+ name: "arc",
1305
+ async isAvailable({ scopes }) {
1306
+ const resource = mapScopesToResource(scopes);
1307
+ if (!resource) {
1308
+ logger$k.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
1309
+ return false;
1310
+ }
1311
+ const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
1312
+ if (!result) {
1313
+ logger$k.info(`${msiName$3}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
1314
+ }
1315
+ return result;
1316
+ },
1317
+ async getToken(configuration, getTokenOptions = {}) {
1318
+ var _a;
1319
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1320
+ if (clientId) {
1321
+ logger$k.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1322
+ }
1323
+ if (resourceId) {
1324
+ logger$k.warning(`${msiName$3}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
1325
+ }
1326
+ logger$k.info(`${msiName$3}: Authenticating.`);
1327
+ const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), { allowInsecureConnection: true });
1328
+ const filePath = await filePathRequest(identityClient, requestOptions);
1329
+ if (!filePath) {
1330
+ throw new Error(`${msiName$3}: Failed to find the token file.`);
1331
+ }
1332
+ const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
1333
+ (_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
1334
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
1335
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1336
+ allowInsecureConnection: true }));
1337
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1338
+ return (tokenResponse && tokenResponse.accessToken) || null;
1339
+ },
1340
+ };
1360
1341
 
1361
1342
  // Copyright (c) Microsoft Corporation.
1362
1343
  // Licensed under the MIT license.
1363
- const CommonTenantId = "common";
1364
- const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'
1365
- const logger$n = credentialLogger("VisualStudioCodeCredential");
1366
- let findCredentials = undefined;
1367
- const vsCodeCredentialControl = {
1368
- setVsCodeCredentialFinder(finder) {
1369
- findCredentials = finder;
1370
- },
1371
- };
1372
- // Map of unsupported Tenant IDs and the errors we will be throwing.
1373
- const unsupportedTenantIds = {
1374
- adfs: "The VisualStudioCodeCredential does not support authentication with ADFS tenants.",
1375
- };
1376
- function checkUnsupportedTenant(tenantId) {
1377
- // If the Tenant ID isn't supported, we throw.
1378
- const unsupportedTenantError = unsupportedTenantIds[tenantId];
1379
- if (unsupportedTenantError) {
1380
- throw new CredentialUnavailableError(unsupportedTenantError);
1344
+ /**
1345
+ * @internal
1346
+ */
1347
+ const logger$j = credentialLogger("IdentityUtils");
1348
+ /**
1349
+ * Latest AuthenticationRecord version
1350
+ * @internal
1351
+ */
1352
+ const LatestAuthenticationRecordVersion = "1.0";
1353
+ /**
1354
+ * Ensures the validity of the MSAL token
1355
+ * @internal
1356
+ */
1357
+ function ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
1358
+ const error = (message) => {
1359
+ logger$j.getToken.info(message);
1360
+ return new AuthenticationRequiredError({
1361
+ scopes: Array.isArray(scopes) ? scopes : [scopes],
1362
+ getTokenOptions,
1363
+ message,
1364
+ });
1365
+ };
1366
+ if (!msalToken) {
1367
+ throw error("No response");
1368
+ }
1369
+ if (!msalToken.expiresOn) {
1370
+ throw error(`Response had no "expiresOn" property.`);
1371
+ }
1372
+ if (!msalToken.accessToken) {
1373
+ throw error(`Response had no "accessToken" property.`);
1374
+ }
1375
+ }
1376
+ /**
1377
+ * Generates a valid authority by combining a host with a tenantId.
1378
+ * @internal
1379
+ */
1380
+ function getAuthority(tenantId, host) {
1381
+ if (!host) {
1382
+ host = DefaultAuthorityHost;
1383
+ }
1384
+ if (new RegExp(`${tenantId}/?$`).test(host)) {
1385
+ return host;
1386
+ }
1387
+ if (host.endsWith("/")) {
1388
+ return host + tenantId;
1389
+ }
1390
+ else {
1391
+ return `${host}/${tenantId}`;
1392
+ }
1393
+ }
1394
+ /**
1395
+ * Generates the known authorities.
1396
+ * If the Tenant Id is `adfs`, the authority can't be validated since the format won't match the expected one.
1397
+ * For that reason, we have to force MSAL to disable validating the authority
1398
+ * by sending it within the known authorities in the MSAL configuration.
1399
+ * @internal
1400
+ */
1401
+ function getKnownAuthorities(tenantId, authorityHost, disableInstanceDiscovery) {
1402
+ if ((tenantId === "adfs" && authorityHost) || disableInstanceDiscovery) {
1403
+ return [authorityHost];
1381
1404
  }
1405
+ return [];
1382
1406
  }
1383
- const mapVSCodeAuthorityHosts = {
1384
- AzureCloud: exports.AzureAuthorityHosts.AzurePublicCloud,
1385
- AzureChina: exports.AzureAuthorityHosts.AzureChina,
1386
- AzureGermanCloud: exports.AzureAuthorityHosts.AzureGermany,
1387
- AzureUSGovernment: exports.AzureAuthorityHosts.AzureGovernment,
1388
- };
1389
1407
  /**
1390
- * Attempts to load a specific property from the VSCode configurations of the current OS.
1391
- * If it fails at any point, returns undefined.
1408
+ * Generates a logger that can be passed to the MSAL clients.
1409
+ * @param credLogger - The logger of the credential.
1410
+ * @internal
1392
1411
  */
1393
- function getPropertyFromVSCode(property) {
1394
- const settingsPath = ["User", "settings.json"];
1395
- // Eventually we can add more folders for more versions of VSCode.
1396
- const vsCodeFolder = "Code";
1397
- const homedir = os.homedir();
1398
- function loadProperty(...pathSegments) {
1399
- const fullPath = path.join(...pathSegments, vsCodeFolder, ...settingsPath);
1400
- const settings = JSON.parse(fs.readFileSync(fullPath, { encoding: "utf8" }));
1401
- return settings[property];
1412
+ const defaultLoggerCallback = (credLogger, platform = coreUtil.isNode ? "Node" : "Browser") => (level, message, containsPii) => {
1413
+ if (containsPii) {
1414
+ return;
1402
1415
  }
1403
- try {
1404
- let appData;
1405
- switch (process.platform) {
1406
- case "win32":
1407
- appData = process.env.APPDATA;
1408
- return appData ? loadProperty(appData) : undefined;
1409
- case "darwin":
1410
- return loadProperty(homedir, "Library", "Application Support");
1411
- case "linux":
1412
- return loadProperty(homedir, ".config");
1413
- default:
1414
- return;
1415
- }
1416
+ switch (level) {
1417
+ case msalCommon__namespace.LogLevel.Error:
1418
+ credLogger.info(`MSAL ${platform} V2 error: ${message}`);
1419
+ return;
1420
+ case msalCommon__namespace.LogLevel.Info:
1421
+ credLogger.info(`MSAL ${platform} V2 info message: ${message}`);
1422
+ return;
1423
+ case msalCommon__namespace.LogLevel.Verbose:
1424
+ credLogger.info(`MSAL ${platform} V2 verbose message: ${message}`);
1425
+ return;
1426
+ case msalCommon__namespace.LogLevel.Warning:
1427
+ credLogger.info(`MSAL ${platform} V2 warning: ${message}`);
1428
+ return;
1416
1429
  }
1417
- catch (e) {
1418
- logger$n.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);
1419
- return;
1430
+ };
1431
+ /**
1432
+ * @internal
1433
+ */
1434
+ function getMSALLogLevel(logLevel) {
1435
+ switch (logLevel) {
1436
+ case "error":
1437
+ return msalCommon__namespace.LogLevel.Error;
1438
+ case "info":
1439
+ return msalCommon__namespace.LogLevel.Info;
1440
+ case "verbose":
1441
+ return msalCommon__namespace.LogLevel.Verbose;
1442
+ case "warning":
1443
+ return msalCommon__namespace.LogLevel.Warning;
1444
+ default:
1445
+ // default msal logging level should be Info
1446
+ return msalCommon__namespace.LogLevel.Info;
1420
1447
  }
1421
1448
  }
1422
1449
  /**
1423
- * Connects to Azure using the credential provided by the VSCode extension 'Azure Account'.
1424
- * Once the user has logged in via the extension, this credential can share the same refresh token
1425
- * that is cached by the extension.
1450
+ * Wraps core-util's randomUUID in order to allow for mocking in tests.
1451
+ * This prepares the library for the upcoming core-util update to ESM.
1426
1452
  *
1427
- * It's a [known issue](https://github.com/Azure/azure-sdk-for-js/issues/20500) that this credential doesn't
1428
- * work with [Azure Account extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account)
1429
- * versions newer than **0.9.11**. A long-term fix to this problem is in progress. In the meantime, consider
1430
- * authenticating with {@link AzureCliCredential}.
1453
+ * @internal
1454
+ * @returns A string containing a random UUID
1431
1455
  */
1432
- class VisualStudioCodeCredential {
1433
- /**
1434
- * Creates an instance of VisualStudioCodeCredential to use for automatically authenticating via VSCode.
1435
- *
1436
- * **Note**: `VisualStudioCodeCredential` is provided by a plugin package:
1437
- * `@azure/identity-vscode`. If this package is not installed and registered
1438
- * using the plugin API (`useIdentityPlugin`), then authentication using
1439
- * `VisualStudioCodeCredential` will not be available.
1440
- *
1441
- * @param options - Options for configuring the client which makes the authentication request.
1442
- */
1443
- constructor(options) {
1444
- // We want to make sure we use the one assigned by the user on the VSCode settings.
1445
- // Or just `AzureCloud` by default.
1446
- this.cloudName = (getPropertyFromVSCode("azure.cloud") || "AzureCloud");
1447
- // Picking an authority host based on the cloud name.
1448
- const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];
1449
- this.identityClient = new IdentityClient(Object.assign({ authorityHost }, options));
1450
- if (options && options.tenantId) {
1451
- checkTenantId(logger$n, options.tenantId);
1452
- this.tenantId = options.tenantId;
1453
- }
1454
- else {
1455
- this.tenantId = CommonTenantId;
1456
- }
1457
- this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
1458
- checkUnsupportedTenant(this.tenantId);
1459
- }
1460
- /**
1461
- * Runs preparations for any further getToken request.
1462
- */
1463
- async prepare() {
1464
- // Attempts to load the tenant from the VSCode configuration file.
1465
- const settingsTenant = getPropertyFromVSCode("azure.tenant");
1466
- if (settingsTenant) {
1467
- this.tenantId = settingsTenant;
1456
+ function randomUUID() {
1457
+ return coreUtil.randomUUID();
1458
+ }
1459
+ /**
1460
+ * Handles MSAL errors.
1461
+ */
1462
+ function handleMsalError(scopes, error, getTokenOptions) {
1463
+ if (error.name === "AuthError" ||
1464
+ error.name === "ClientAuthError" ||
1465
+ error.name === "BrowserAuthError") {
1466
+ const msalError = error;
1467
+ switch (msalError.errorCode) {
1468
+ case "endpoints_resolution_error":
1469
+ logger$j.info(formatError(scopes, error.message));
1470
+ return new CredentialUnavailableError(error.message);
1471
+ case "device_code_polling_cancelled":
1472
+ return new abortController.AbortError("The authentication has been aborted by the caller.");
1473
+ case "consent_required":
1474
+ case "interaction_required":
1475
+ case "login_required":
1476
+ logger$j.info(formatError(scopes, `Authentication returned errorCode ${msalError.errorCode}`));
1477
+ break;
1478
+ default:
1479
+ logger$j.info(formatError(scopes, `Failed to acquire token: ${error.message}`));
1480
+ break;
1468
1481
  }
1469
- checkUnsupportedTenant(this.tenantId);
1470
1482
  }
1471
- /**
1472
- * Runs preparations for any further getToken, but only once.
1473
- */
1474
- prepareOnce() {
1475
- if (!this.preparePromise) {
1476
- this.preparePromise = this.prepare();
1477
- }
1478
- return this.preparePromise;
1483
+ if (error.name === "ClientConfigurationError" ||
1484
+ error.name === "BrowserConfigurationAuthError" ||
1485
+ error.name === "AbortError") {
1486
+ return error;
1479
1487
  }
1480
- /**
1481
- * Returns the token found by searching VSCode's authentication cache or
1482
- * returns null if no token could be found.
1483
- *
1484
- * @param scopes - The list of scopes for which the token will have access.
1485
- * @param options - The options used to configure any requests this
1486
- * `TokenCredential` implementation might make.
1487
- */
1488
- async getToken(scopes, options) {
1489
- var _a, _b;
1490
- await this.prepareOnce();
1491
- const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds, logger$n) || this.tenantId;
1492
- if (findCredentials === undefined) {
1493
- throw new CredentialUnavailableError([
1494
- "No implementation of `VisualStudioCodeCredential` is available.",
1495
- "You must install the identity-vscode plugin package (`npm install --save-dev @azure/identity-vscode`)",
1496
- "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
1497
- "`useIdentityPlugin(vsCodePlugin)` before creating a `VisualStudioCodeCredential`.",
1498
- "To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.",
1499
- ].join(" "));
1500
- }
1501
- let scopeString = typeof scopes === "string" ? scopes : scopes.join(" ");
1502
- // Check to make sure the scope we get back is a valid scope
1503
- if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {
1504
- const error = new Error("Invalid scope was specified by the user or calling client");
1505
- logger$n.getToken.info(formatError(scopes, error));
1506
- throw error;
1507
- }
1508
- if (scopeString.indexOf("offline_access") < 0) {
1509
- scopeString += " offline_access";
1510
- }
1511
- // findCredentials returns an array similar to:
1512
- // [
1513
- // {
1514
- // account: "",
1515
- // password: "",
1516
- // },
1517
- // /* ... */
1518
- // ]
1519
- const credentials = await findCredentials();
1520
- // If we can't find the credential based on the name, we'll pick the first one available.
1521
- const { password: refreshToken } = (_b = (_a = credentials.find(({ account }) => account === this.cloudName)) !== null && _a !== void 0 ? _a : credentials[0]) !== null && _b !== void 0 ? _b : {};
1522
- if (refreshToken) {
1523
- const tokenResponse = await this.identityClient.refreshAccessToken(tenantId, AzureAccountClientId, scopeString, refreshToken, undefined);
1524
- if (tokenResponse) {
1525
- logger$n.getToken.info(formatSuccess(scopes));
1526
- return tokenResponse.accessToken;
1527
- }
1528
- else {
1529
- const error = new CredentialUnavailableError("Could not retrieve the token associated with Visual Studio Code. Have you connected using the 'Azure Account' extension recently? To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.");
1530
- logger$n.getToken.info(formatError(scopes, error));
1531
- throw error;
1532
- }
1533
- }
1534
- else {
1535
- const error = new CredentialUnavailableError("Could not retrieve the token associated with Visual Studio Code. Did you connect using the 'Azure Account' extension? To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.");
1536
- logger$n.getToken.info(formatError(scopes, error));
1537
- throw error;
1538
- }
1488
+ if (error.name === "NativeAuthError") {
1489
+ logger$j.info(formatError(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`));
1490
+ return error;
1539
1491
  }
1492
+ return new AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message });
1493
+ }
1494
+ // transformations.ts
1495
+ function publicToMsal(account) {
1496
+ const [environment] = account.authority.match(/([a-z]*\.[a-z]*\.[a-z]*)/) || [""];
1497
+ return Object.assign(Object.assign({}, account), { localAccountId: account.homeAccountId, environment });
1498
+ }
1499
+ function msalToPublic(clientId, account) {
1500
+ const record = {
1501
+ authority: getAuthority(account.tenantId, account.environment),
1502
+ homeAccountId: account.homeAccountId,
1503
+ tenantId: account.tenantId || DefaultTenantId,
1504
+ username: account.username,
1505
+ clientId,
1506
+ version: LatestAuthenticationRecordVersion,
1507
+ };
1508
+ return record;
1540
1509
  }
1541
-
1542
- // Copyright (c) Microsoft Corporation.
1543
- // Licensed under the MIT license.
1544
- /**
1545
- * The context passed to an Identity plugin. This contains objects that
1546
- * plugins can use to set backend implementations.
1547
- * @internal
1548
- */
1549
- const pluginContext = {
1550
- cachePluginControl: msalNodeFlowCacheControl,
1551
- nativeBrokerPluginControl: msalNodeFlowNativeBrokerControl,
1552
- vsCodeCredentialControl: vsCodeCredentialControl,
1553
- };
1554
1510
  /**
1555
- * Extend Azure Identity with additional functionality. Pass a plugin from
1556
- * a plugin package, such as:
1557
- *
1558
- * - `@azure/identity-cache-persistence`: provides persistent token caching
1559
- * - `@azure/identity-vscode`: provides the dependencies of
1560
- * `VisualStudioCodeCredential` and enables it
1561
- *
1562
- * Example:
1563
- *
1564
- * ```javascript
1565
- * import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
1511
+ * Serializes an `AuthenticationRecord` into a string.
1566
1512
  *
1567
- * import { useIdentityPlugin, DefaultAzureCredential } from "@azure/identity";
1568
- * useIdentityPlugin(cachePersistencePlugin);
1513
+ * The output of a serialized authentication record will contain the following properties:
1569
1514
  *
1570
- * // The plugin has the capability to extend `DefaultAzureCredential` and to
1571
- * // add middleware to the underlying credentials, such as persistence.
1572
- * const credential = new DefaultAzureCredential({
1573
- * tokenCachePersistenceOptions: {
1574
- * enabled: true
1575
- * }
1576
- * });
1577
- * ```
1515
+ * - "authority"
1516
+ * - "homeAccountId"
1517
+ * - "clientId"
1518
+ * - "tenantId"
1519
+ * - "username"
1520
+ * - "version"
1578
1521
  *
1579
- * @param plugin - the plugin to register
1522
+ * To later convert this string to a serialized `AuthenticationRecord`, please use the exported function `deserializeAuthenticationRecord()`.
1580
1523
  */
1581
- function useIdentityPlugin(plugin) {
1582
- plugin(pluginContext);
1524
+ function serializeAuthenticationRecord(record) {
1525
+ return JSON.stringify(record);
1583
1526
  }
1584
-
1585
- // Copyright (c) Microsoft Corporation.
1586
- // Licensed under the MIT license.
1587
- const msiName$6 = "ManagedIdentityCredential - AppServiceMSI 2017";
1588
- const logger$m = credentialLogger(msiName$6);
1589
1527
  /**
1590
- * Generates the options used on the request for an access token.
1528
+ * Deserializes a previously serialized authentication record from a string into an object.
1529
+ *
1530
+ * The input string must contain the following properties:
1531
+ *
1532
+ * - "authority"
1533
+ * - "homeAccountId"
1534
+ * - "clientId"
1535
+ * - "tenantId"
1536
+ * - "username"
1537
+ * - "version"
1538
+ *
1539
+ * If the version we receive is unsupported, an error will be thrown.
1540
+ *
1541
+ * At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
1542
+ *
1543
+ * @param serializedRecord - Authentication record previously serialized into string.
1544
+ * @returns AuthenticationRecord.
1591
1545
  */
1592
- function prepareRequestOptions$5(scopes, clientId) {
1593
- const resource = mapScopesToResource(scopes);
1594
- if (!resource) {
1595
- throw new Error(`${msiName$6}: Multiple scopes are not supported.`);
1596
- }
1597
- const queryParameters = {
1598
- resource,
1599
- "api-version": "2017-09-01",
1600
- };
1601
- if (clientId) {
1602
- queryParameters.clientid = clientId;
1603
- }
1604
- const query = new URLSearchParams(queryParameters);
1605
- // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1606
- if (!process.env.MSI_ENDPOINT) {
1607
- throw new Error(`${msiName$6}: Missing environment variable: MSI_ENDPOINT`);
1608
- }
1609
- if (!process.env.MSI_SECRET) {
1610
- throw new Error(`${msiName$6}: Missing environment variable: MSI_SECRET`);
1546
+ function deserializeAuthenticationRecord(serializedRecord) {
1547
+ const parsed = JSON.parse(serializedRecord);
1548
+ if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) {
1549
+ throw Error("Unsupported AuthenticationRecord version");
1611
1550
  }
1612
- return {
1613
- url: `${process.env.MSI_ENDPOINT}?${query.toString()}`,
1614
- method: "GET",
1615
- headers: coreRestPipeline.createHttpHeaders({
1616
- Accept: "application/json",
1617
- secret: process.env.MSI_SECRET,
1618
- }),
1619
- };
1551
+ return parsed;
1620
1552
  }
1621
- /**
1622
- * Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
1623
- */
1624
- const appServiceMsi2017 = {
1625
- name: "appServiceMsi2017",
1626
- async isAvailable({ scopes }) {
1627
- const resource = mapScopesToResource(scopes);
1628
- if (!resource) {
1629
- logger$m.info(`${msiName$6}: Unavailable. Multiple scopes are not supported.`);
1630
- return false;
1631
- }
1632
- const env = process.env;
1633
- const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
1634
- if (!result) {
1635
- logger$m.info(`${msiName$6}: Unavailable. The environment variables needed are: MSI_ENDPOINT and MSI_SECRET.`);
1636
- }
1637
- return result;
1638
- },
1639
- async getToken(configuration, getTokenOptions = {}) {
1640
- const { identityClient, scopes, clientId, resourceId } = configuration;
1641
- if (resourceId) {
1642
- logger$m.warning(`${msiName$6}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
1643
- }
1644
- logger$m.info(`${msiName$6}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
1645
- const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId)), {
1646
- // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1647
- allowInsecureConnection: true }));
1648
- const tokenResponse = await identityClient.sendTokenRequest(request);
1649
- return (tokenResponse && tokenResponse.accessToken) || null;
1650
- },
1651
- };
1652
1553
 
1653
1554
  // Copyright (c) Microsoft Corporation.
1654
1555
  // Licensed under the MIT license.
1655
- const msiName$5 = "ManagedIdentityCredential - CloudShellMSI";
1656
- const logger$l = credentialLogger(msiName$5);
1657
- /**
1658
- * Generates the options used on the request for an access token.
1659
- */
1660
- function prepareRequestOptions$4(scopes, clientId, resourceId) {
1661
- const resource = mapScopesToResource(scopes);
1662
- if (!resource) {
1663
- throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
1664
- }
1665
- const body = {
1666
- resource,
1667
- };
1668
- if (clientId) {
1669
- body.client_id = clientId;
1670
- }
1671
- if (resourceId) {
1672
- body.msi_res_id = resourceId;
1673
- }
1674
- // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1675
- if (!process.env.MSI_ENDPOINT) {
1676
- throw new Error(`${msiName$5}: Missing environment variable: MSI_ENDPOINT`);
1677
- }
1678
- const params = new URLSearchParams(body);
1679
- return {
1680
- url: process.env.MSI_ENDPOINT,
1681
- method: "POST",
1682
- body: params.toString(),
1683
- headers: coreRestPipeline.createHttpHeaders({
1684
- Accept: "application/json",
1685
- Metadata: "true",
1686
- "Content-Type": "application/x-www-form-urlencoded",
1687
- }),
1688
- };
1689
- }
1690
1556
  /**
1691
- * Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
1692
- * Since Azure Managed Identities aren't available in the Azure Cloud Shell, we log a warning for users that try to access cloud shell using user assigned identity.
1557
+ * Helps specify a regional authority, or "AutoDiscoverRegion" to auto-detect the region.
1693
1558
  */
1694
- const cloudShellMsi = {
1695
- name: "cloudShellMsi",
1696
- async isAvailable({ scopes }) {
1697
- const resource = mapScopesToResource(scopes);
1698
- if (!resource) {
1699
- logger$l.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
1700
- return false;
1701
- }
1702
- const result = Boolean(process.env.MSI_ENDPOINT);
1703
- if (!result) {
1704
- logger$l.info(`${msiName$5}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
1705
- }
1706
- return result;
1707
- },
1708
- async getToken(configuration, getTokenOptions = {}) {
1709
- const { identityClient, scopes, clientId, resourceId } = configuration;
1710
- if (clientId) {
1711
- logger$l.warning(`${msiName$5}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1712
- }
1713
- if (resourceId) {
1714
- logger$l.warning(`${msiName$5}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
1715
- }
1716
- logger$l.info(`${msiName$5}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
1717
- const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
1718
- // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1719
- allowInsecureConnection: true }));
1720
- const tokenResponse = await identityClient.sendTokenRequest(request);
1721
- return (tokenResponse && tokenResponse.accessToken) || null;
1722
- },
1723
- };
1559
+ var RegionalAuthority;
1560
+ (function (RegionalAuthority) {
1561
+ /** Instructs MSAL to attempt to discover the region */
1562
+ RegionalAuthority["AutoDiscoverRegion"] = "AutoDiscoverRegion";
1563
+ /** Uses the {@link RegionalAuthority} for the Azure 'westus' region. */
1564
+ RegionalAuthority["USWest"] = "westus";
1565
+ /** Uses the {@link RegionalAuthority} for the Azure 'westus2' region. */
1566
+ RegionalAuthority["USWest2"] = "westus2";
1567
+ /** Uses the {@link RegionalAuthority} for the Azure 'centralus' region. */
1568
+ RegionalAuthority["USCentral"] = "centralus";
1569
+ /** Uses the {@link RegionalAuthority} for the Azure 'eastus' region. */
1570
+ RegionalAuthority["USEast"] = "eastus";
1571
+ /** Uses the {@link RegionalAuthority} for the Azure 'eastus2' region. */
1572
+ RegionalAuthority["USEast2"] = "eastus2";
1573
+ /** Uses the {@link RegionalAuthority} for the Azure 'northcentralus' region. */
1574
+ RegionalAuthority["USNorthCentral"] = "northcentralus";
1575
+ /** Uses the {@link RegionalAuthority} for the Azure 'southcentralus' region. */
1576
+ RegionalAuthority["USSouthCentral"] = "southcentralus";
1577
+ /** Uses the {@link RegionalAuthority} for the Azure 'westcentralus' region. */
1578
+ RegionalAuthority["USWestCentral"] = "westcentralus";
1579
+ /** Uses the {@link RegionalAuthority} for the Azure 'canadacentral' region. */
1580
+ RegionalAuthority["CanadaCentral"] = "canadacentral";
1581
+ /** Uses the {@link RegionalAuthority} for the Azure 'canadaeast' region. */
1582
+ RegionalAuthority["CanadaEast"] = "canadaeast";
1583
+ /** Uses the {@link RegionalAuthority} for the Azure 'brazilsouth' region. */
1584
+ RegionalAuthority["BrazilSouth"] = "brazilsouth";
1585
+ /** Uses the {@link RegionalAuthority} for the Azure 'northeurope' region. */
1586
+ RegionalAuthority["EuropeNorth"] = "northeurope";
1587
+ /** Uses the {@link RegionalAuthority} for the Azure 'westeurope' region. */
1588
+ RegionalAuthority["EuropeWest"] = "westeurope";
1589
+ /** Uses the {@link RegionalAuthority} for the Azure 'uksouth' region. */
1590
+ RegionalAuthority["UKSouth"] = "uksouth";
1591
+ /** Uses the {@link RegionalAuthority} for the Azure 'ukwest' region. */
1592
+ RegionalAuthority["UKWest"] = "ukwest";
1593
+ /** Uses the {@link RegionalAuthority} for the Azure 'francecentral' region. */
1594
+ RegionalAuthority["FranceCentral"] = "francecentral";
1595
+ /** Uses the {@link RegionalAuthority} for the Azure 'francesouth' region. */
1596
+ RegionalAuthority["FranceSouth"] = "francesouth";
1597
+ /** Uses the {@link RegionalAuthority} for the Azure 'switzerlandnorth' region. */
1598
+ RegionalAuthority["SwitzerlandNorth"] = "switzerlandnorth";
1599
+ /** Uses the {@link RegionalAuthority} for the Azure 'switzerlandwest' region. */
1600
+ RegionalAuthority["SwitzerlandWest"] = "switzerlandwest";
1601
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanynorth' region. */
1602
+ RegionalAuthority["GermanyNorth"] = "germanynorth";
1603
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanywestcentral' region. */
1604
+ RegionalAuthority["GermanyWestCentral"] = "germanywestcentral";
1605
+ /** Uses the {@link RegionalAuthority} for the Azure 'norwaywest' region. */
1606
+ RegionalAuthority["NorwayWest"] = "norwaywest";
1607
+ /** Uses the {@link RegionalAuthority} for the Azure 'norwayeast' region. */
1608
+ RegionalAuthority["NorwayEast"] = "norwayeast";
1609
+ /** Uses the {@link RegionalAuthority} for the Azure 'eastasia' region. */
1610
+ RegionalAuthority["AsiaEast"] = "eastasia";
1611
+ /** Uses the {@link RegionalAuthority} for the Azure 'southeastasia' region. */
1612
+ RegionalAuthority["AsiaSouthEast"] = "southeastasia";
1613
+ /** Uses the {@link RegionalAuthority} for the Azure 'japaneast' region. */
1614
+ RegionalAuthority["JapanEast"] = "japaneast";
1615
+ /** Uses the {@link RegionalAuthority} for the Azure 'japanwest' region. */
1616
+ RegionalAuthority["JapanWest"] = "japanwest";
1617
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiaeast' region. */
1618
+ RegionalAuthority["AustraliaEast"] = "australiaeast";
1619
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiasoutheast' region. */
1620
+ RegionalAuthority["AustraliaSouthEast"] = "australiasoutheast";
1621
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiacentral' region. */
1622
+ RegionalAuthority["AustraliaCentral"] = "australiacentral";
1623
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiacentral2' region. */
1624
+ RegionalAuthority["AustraliaCentral2"] = "australiacentral2";
1625
+ /** Uses the {@link RegionalAuthority} for the Azure 'centralindia' region. */
1626
+ RegionalAuthority["IndiaCentral"] = "centralindia";
1627
+ /** Uses the {@link RegionalAuthority} for the Azure 'southindia' region. */
1628
+ RegionalAuthority["IndiaSouth"] = "southindia";
1629
+ /** Uses the {@link RegionalAuthority} for the Azure 'westindia' region. */
1630
+ RegionalAuthority["IndiaWest"] = "westindia";
1631
+ /** Uses the {@link RegionalAuthority} for the Azure 'koreasouth' region. */
1632
+ RegionalAuthority["KoreaSouth"] = "koreasouth";
1633
+ /** Uses the {@link RegionalAuthority} for the Azure 'koreacentral' region. */
1634
+ RegionalAuthority["KoreaCentral"] = "koreacentral";
1635
+ /** Uses the {@link RegionalAuthority} for the Azure 'uaecentral' region. */
1636
+ RegionalAuthority["UAECentral"] = "uaecentral";
1637
+ /** Uses the {@link RegionalAuthority} for the Azure 'uaenorth' region. */
1638
+ RegionalAuthority["UAENorth"] = "uaenorth";
1639
+ /** Uses the {@link RegionalAuthority} for the Azure 'southafricanorth' region. */
1640
+ RegionalAuthority["SouthAfricaNorth"] = "southafricanorth";
1641
+ /** Uses the {@link RegionalAuthority} for the Azure 'southafricawest' region. */
1642
+ RegionalAuthority["SouthAfricaWest"] = "southafricawest";
1643
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinanorth' region. */
1644
+ RegionalAuthority["ChinaNorth"] = "chinanorth";
1645
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinaeast' region. */
1646
+ RegionalAuthority["ChinaEast"] = "chinaeast";
1647
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinanorth2' region. */
1648
+ RegionalAuthority["ChinaNorth2"] = "chinanorth2";
1649
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinaeast2' region. */
1650
+ RegionalAuthority["ChinaEast2"] = "chinaeast2";
1651
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanycentral' region. */
1652
+ RegionalAuthority["GermanyCentral"] = "germanycentral";
1653
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanynortheast' region. */
1654
+ RegionalAuthority["GermanyNorthEast"] = "germanynortheast";
1655
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgovvirginia' region. */
1656
+ RegionalAuthority["GovernmentUSVirginia"] = "usgovvirginia";
1657
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgoviowa' region. */
1658
+ RegionalAuthority["GovernmentUSIowa"] = "usgoviowa";
1659
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgovarizona' region. */
1660
+ RegionalAuthority["GovernmentUSArizona"] = "usgovarizona";
1661
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgovtexas' region. */
1662
+ RegionalAuthority["GovernmentUSTexas"] = "usgovtexas";
1663
+ /** Uses the {@link RegionalAuthority} for the Azure 'usdodeast' region. */
1664
+ RegionalAuthority["GovernmentUSDodEast"] = "usdodeast";
1665
+ /** Uses the {@link RegionalAuthority} for the Azure 'usdodcentral' region. */
1666
+ RegionalAuthority["GovernmentUSDodCentral"] = "usdodcentral";
1667
+ })(RegionalAuthority || (RegionalAuthority = {}));
1724
1668
 
1725
1669
  // Copyright (c) Microsoft Corporation.
1726
1670
  // Licensed under the MIT license.
1727
- const msiName$4 = "ManagedIdentityCredential - IMDS";
1728
- const logger$k = credentialLogger(msiName$4);
1729
1671
  /**
1730
- * Generates the options used on the request for an access token.
1672
+ * MSAL partial base client for Node.js.
1673
+ *
1674
+ * It completes the input configuration with some default values.
1675
+ * It also provides with utility protected methods that can be used from any of the clients,
1676
+ * which includes handlers for successful responses and errors.
1677
+ *
1678
+ * @internal
1731
1679
  */
1732
- function prepareRequestOptions$3(scopes, clientId, resourceId, options) {
1733
- var _a;
1734
- const resource = mapScopesToResource(scopes);
1735
- if (!resource) {
1736
- throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
1680
+ class MsalNode {
1681
+ constructor(options) {
1682
+ var _a, _b, _c, _d, _e, _f, _g;
1683
+ this.app = {};
1684
+ this.caeApp = {};
1685
+ this.requiresConfidential = false;
1686
+ this.logger = options.logger;
1687
+ this.msalConfig = this.defaultNodeMsalConfig(options);
1688
+ this.tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
1689
+ this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
1690
+ this.clientId = this.msalConfig.auth.clientId;
1691
+ if (options === null || options === void 0 ? void 0 : options.getAssertion) {
1692
+ this.getAssertion = options.getAssertion;
1693
+ }
1694
+ this.enableBroker = (_b = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _b === void 0 ? void 0 : _b.enabled;
1695
+ this.enableMsaPassthrough = (_c = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough;
1696
+ this.parentWindowHandle = (_d = options.brokerOptions) === null || _d === void 0 ? void 0 : _d.parentWindowHandle;
1697
+ // If persistence has been configured
1698
+ if (persistenceProvider !== undefined && ((_e = options.tokenCachePersistenceOptions) === null || _e === void 0 ? void 0 : _e.enabled)) {
1699
+ const nonCaeOptions = Object.assign({ name: `${options.tokenCachePersistenceOptions.name}.${CACHE_NON_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
1700
+ const caeOptions = Object.assign({ name: `${options.tokenCachePersistenceOptions.name}.${CACHE_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
1701
+ this.createCachePlugin = () => persistenceProvider(nonCaeOptions);
1702
+ this.createCachePluginCae = () => persistenceProvider(caeOptions);
1703
+ }
1704
+ else if ((_f = options.tokenCachePersistenceOptions) === null || _f === void 0 ? void 0 : _f.enabled) {
1705
+ throw new Error([
1706
+ "Persistent token caching was requested, but no persistence provider was configured.",
1707
+ "You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)",
1708
+ "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
1709
+ "`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`.",
1710
+ ].join(" "));
1711
+ }
1712
+ // If broker has not been configured
1713
+ if (!hasNativeBroker() && this.enableBroker) {
1714
+ throw new Error([
1715
+ "Broker for WAM was requested to be enabled, but no native broker was configured.",
1716
+ "You must install the identity-broker plugin package (`npm install --save @azure/identity-broker`)",
1717
+ "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
1718
+ "`useIdentityPlugin(createNativeBrokerPlugin())` before using `enableBroker`.",
1719
+ ].join(" "));
1720
+ }
1721
+ this.azureRegion = (_g = options.regionalAuthority) !== null && _g !== void 0 ? _g : process.env.AZURE_REGIONAL_AUTHORITY_NAME;
1722
+ if (this.azureRegion === RegionalAuthority.AutoDiscoverRegion) {
1723
+ this.azureRegion = "AUTO_DISCOVER";
1724
+ }
1737
1725
  }
1738
- const { skipQuery, skipMetadataHeader } = options || {};
1739
- let query = "";
1740
- // Pod Identity will try to process this request even if the Metadata header is missing.
1741
- // We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
1742
- if (!skipQuery) {
1743
- const queryParameters = {
1744
- resource,
1745
- "api-version": imdsApiVersion,
1726
+ /**
1727
+ * Generates a MSAL configuration that generally works for Node.js
1728
+ */
1729
+ defaultNodeMsalConfig(options) {
1730
+ var _a;
1731
+ const clientId = options.clientId || DeveloperSignOnClientId;
1732
+ const tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
1733
+ this.authorityHost = options.authorityHost || process.env.AZURE_AUTHORITY_HOST;
1734
+ const authority = getAuthority(tenantId, this.authorityHost);
1735
+ this.identityClient = new IdentityClient(Object.assign(Object.assign({}, options.tokenCredentialOptions), { authorityHost: authority, loggingOptions: options.loggingOptions }));
1736
+ const clientCapabilities = [];
1737
+ return {
1738
+ auth: {
1739
+ clientId,
1740
+ authority,
1741
+ knownAuthorities: getKnownAuthorities(tenantId, authority, options.disableInstanceDiscovery),
1742
+ clientCapabilities,
1743
+ },
1744
+ // Cache is defined in this.prepare();
1745
+ system: {
1746
+ networkClient: this.identityClient,
1747
+ loggerOptions: {
1748
+ loggerCallback: defaultLoggerCallback(options.logger),
1749
+ logLevel: getMSALLogLevel(logger$q.getLogLevel()),
1750
+ piiLoggingEnabled: (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.enableUnsafeSupportLogging,
1751
+ },
1752
+ },
1746
1753
  };
1747
- if (clientId) {
1748
- queryParameters.client_id = clientId;
1754
+ }
1755
+ getApp(appType, enableCae) {
1756
+ const app = enableCae ? this.caeApp : this.app;
1757
+ if (appType === "publicFirst") {
1758
+ return (app.public || app.confidential);
1749
1759
  }
1750
- if (resourceId) {
1751
- queryParameters.msi_res_id = resourceId;
1760
+ else if (appType === "confidentialFirst") {
1761
+ return (app.confidential || app.public);
1762
+ }
1763
+ else if (appType === "confidential") {
1764
+ return app.confidential;
1765
+ }
1766
+ else {
1767
+ return app.public;
1752
1768
  }
1753
- const params = new URLSearchParams(queryParameters);
1754
- query = `?${params.toString()}`;
1755
- }
1756
- const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
1757
- const rawHeaders = {
1758
- Accept: "application/json",
1759
- Metadata: "true",
1760
- };
1761
- // Remove the Metadata header to invoke a request error from some IMDS endpoints.
1762
- if (skipMetadataHeader) {
1763
- delete rawHeaders.Metadata;
1764
1769
  }
1765
- return {
1766
- // In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
1767
- url: `${url}${query}`,
1768
- method: "GET",
1769
- headers: coreRestPipeline.createHttpHeaders(rawHeaders),
1770
- };
1771
- }
1772
- // 800ms -> 1600ms -> 3200ms
1773
- const imdsMsiRetryConfig = {
1774
- maxRetries: 3,
1775
- startDelayInMs: 800,
1776
- intervalIncrement: 2,
1777
- };
1778
- /**
1779
- * Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
1780
- */
1781
- const imdsMsi = {
1782
- name: "imdsMsi",
1783
- async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
1784
- const resource = mapScopesToResource(scopes);
1785
- if (!resource) {
1786
- logger$k.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
1787
- return false;
1770
+ /**
1771
+ * Prepares the MSAL applications.
1772
+ */
1773
+ async init(options) {
1774
+ if (options === null || options === void 0 ? void 0 : options.abortSignal) {
1775
+ options.abortSignal.addEventListener("abort", () => {
1776
+ // This will abort any pending request in the IdentityClient,
1777
+ // based on the received or generated correlationId
1778
+ this.identityClient.abortRequests(options.correlationId);
1779
+ });
1788
1780
  }
1789
- // if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
1790
- if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1791
- return true;
1781
+ const app = (options === null || options === void 0 ? void 0 : options.enableCae) ? this.caeApp : this.app;
1782
+ if (options === null || options === void 0 ? void 0 : options.enableCae) {
1783
+ this.msalConfig.auth.clientCapabilities = ["cp1"];
1792
1784
  }
1793
- if (!identityClient) {
1794
- throw new Error("Missing IdentityClient");
1785
+ if (app.public || app.confidential) {
1786
+ return;
1795
1787
  }
1796
- const requestOptions = prepareRequestOptions$3(resource, clientId, resourceId, {
1797
- skipMetadataHeader: true,
1798
- skipQuery: true,
1799
- });
1800
- return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
1801
- var _a, _b;
1802
- requestOptions.tracingOptions = options.tracingOptions;
1803
- // Create a request with a timeout since we expect that
1804
- // not having a "Metadata" header should cause an error to be
1805
- // returned quickly from the endpoint, proving its availability.
1806
- const request = coreRestPipeline.createPipelineRequest(requestOptions);
1807
- // Default to 1000 if the default of 0 is used.
1808
- // Negative values can still be used to disable the timeout.
1809
- request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
1810
- // This MSI uses the imdsEndpoint to get the token, which only uses http://
1811
- request.allowInsecureConnection = true;
1812
- let response;
1813
- try {
1814
- logger$k.info(`${msiName$4}: Pinging the Azure IMDS endpoint`);
1815
- response = await identityClient.sendRequest(request);
1816
- }
1817
- catch (err) {
1818
- // If the request failed, or Node.js was unable to establish a connection,
1819
- // or the host was down, we'll assume the IMDS endpoint isn't available.
1820
- if (coreUtil.isError(err)) {
1821
- logger$k.verbose(`${msiName$4}: Caught error ${err.name}: ${err.message}`);
1822
- }
1823
- // This is a special case for Docker Desktop which responds with a 403 with a message that contains "A socket operation was attempted to an unreachable network"
1824
- // rather than just timing out, as expected.
1825
- logger$k.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
1826
- return false;
1788
+ if ((options === null || options === void 0 ? void 0 : options.enableCae) && this.createCachePluginCae !== undefined) {
1789
+ this.msalConfig.cache = {
1790
+ cachePlugin: await this.createCachePluginCae(),
1791
+ };
1792
+ }
1793
+ if (this.createCachePlugin !== undefined) {
1794
+ this.msalConfig.cache = {
1795
+ cachePlugin: await this.createCachePlugin(),
1796
+ };
1797
+ }
1798
+ if (hasNativeBroker() && this.enableBroker) {
1799
+ this.msalConfig.broker = {
1800
+ nativeBrokerPlugin: nativeBrokerInfo.broker,
1801
+ };
1802
+ if (!this.parentWindowHandle) {
1803
+ // error should have been thrown from within the constructor of InteractiveBrowserCredential
1804
+ this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
1827
1805
  }
1828
- if (response.status === 403) {
1829
- if ((_b = response.bodyAsText) === null || _b === void 0 ? void 0 : _b.includes("A socket operation was attempted to an unreachable network")) {
1830
- logger$k.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
1831
- logger$k.info(`${msiName$4}: ${response.bodyAsText}`);
1832
- return false;
1833
- }
1806
+ }
1807
+ if (options === null || options === void 0 ? void 0 : options.enableCae) {
1808
+ this.caeApp.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
1809
+ }
1810
+ else {
1811
+ this.app.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
1812
+ }
1813
+ if (this.getAssertion) {
1814
+ this.msalConfig.auth.clientAssertion = await this.getAssertion();
1815
+ }
1816
+ // The confidential client requires either a secret, assertion or certificate.
1817
+ if (this.msalConfig.auth.clientSecret ||
1818
+ this.msalConfig.auth.clientAssertion ||
1819
+ this.msalConfig.auth.clientCertificate) {
1820
+ if (options === null || options === void 0 ? void 0 : options.enableCae) {
1821
+ this.caeApp.confidential = new msalCommon__namespace.ConfidentialClientApplication(this.msalConfig);
1822
+ }
1823
+ else {
1824
+ this.app.confidential = new msalCommon__namespace.ConfidentialClientApplication(this.msalConfig);
1834
1825
  }
1835
- // If we received any response, the endpoint is available
1836
- logger$k.info(`${msiName$4}: The Azure IMDS endpoint is available`);
1837
- return true;
1838
- });
1839
- },
1840
- async getToken(configuration, getTokenOptions = {}) {
1841
- const { identityClient, scopes, clientId, resourceId } = configuration;
1842
- if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1843
- logger$k.info(`${msiName$4}: Using the Azure IMDS endpoint coming from the environment variable AZURE_POD_IDENTITY_AUTHORITY_HOST=${process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST}.`);
1844
1826
  }
1845
1827
  else {
1846
- logger$k.info(`${msiName$4}: Using the default Azure IMDS endpoint ${imdsHost}.`);
1847
- }
1848
- let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
1849
- for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
1850
- try {
1851
- const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
1852
- const tokenResponse = await identityClient.sendTokenRequest(request);
1853
- return (tokenResponse && tokenResponse.accessToken) || null;
1854
- }
1855
- catch (error) {
1856
- if (error.statusCode === 404) {
1857
- await coreUtil.delay(nextDelayInMs);
1858
- nextDelayInMs *= imdsMsiRetryConfig.intervalIncrement;
1859
- continue;
1860
- }
1861
- throw error;
1828
+ if (this.requiresConfidential) {
1829
+ throw new Error("Unable to generate the MSAL confidential client. Missing either the client's secret, certificate or assertion.");
1862
1830
  }
1863
1831
  }
1864
- throw new AuthenticationError(404, `${msiName$4}: Failed to retrieve IMDS token after ${imdsMsiRetryConfig.maxRetries} retries.`);
1865
- },
1866
- };
1867
-
1868
- // Copyright (c) Microsoft Corporation.
1869
- // Licensed under the MIT license.
1870
- const msiName$3 = "ManagedIdentityCredential - Azure Arc MSI";
1871
- const logger$j = credentialLogger(msiName$3);
1872
- /**
1873
- * Generates the options used on the request for an access token.
1874
- */
1875
- function prepareRequestOptions$2(scopes, clientId, resourceId) {
1876
- const resource = mapScopesToResource(scopes);
1877
- if (!resource) {
1878
- throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
1879
- }
1880
- const queryParameters = {
1881
- resource,
1882
- "api-version": azureArcAPIVersion,
1883
- };
1884
- if (clientId) {
1885
- queryParameters.client_id = clientId;
1886
1832
  }
1887
- if (resourceId) {
1888
- queryParameters.msi_res_id = resourceId;
1889
- }
1890
- // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1891
- if (!process.env.IDENTITY_ENDPOINT) {
1892
- throw new Error(`${msiName$3}: Missing environment variable: IDENTITY_ENDPOINT`);
1833
+ /**
1834
+ * Allows the cancellation of a MSAL request.
1835
+ */
1836
+ withCancellation(promise, abortSignal, onCancel) {
1837
+ return new Promise((resolve, reject) => {
1838
+ promise
1839
+ .then((msalToken) => {
1840
+ return resolve(msalToken);
1841
+ })
1842
+ .catch(reject);
1843
+ if (abortSignal) {
1844
+ abortSignal.addEventListener("abort", () => {
1845
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
1846
+ });
1847
+ }
1848
+ });
1893
1849
  }
1894
- const query = new URLSearchParams(queryParameters);
1895
- return coreRestPipeline.createPipelineRequest({
1896
- // Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
1897
- url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
1898
- method: "GET",
1899
- headers: coreRestPipeline.createHttpHeaders({
1900
- Accept: "application/json",
1901
- Metadata: "true",
1902
- }),
1903
- });
1904
- }
1905
- /**
1906
- * Retrieves the file contents at the given path using promises.
1907
- * Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
1908
- */
1909
- function readFileAsync$1(path, options) {
1910
- return new Promise((resolve, reject) => fs.readFile(path, options, (err, data) => {
1911
- if (err) {
1912
- reject(err);
1850
+ /**
1851
+ * Returns the existing account, attempts to load the account from MSAL.
1852
+ */
1853
+ async getActiveAccount(enableCae = false) {
1854
+ if (this.account) {
1855
+ return this.account;
1913
1856
  }
1914
- resolve(data);
1915
- }));
1916
- }
1917
- /**
1918
- * Does a request to the authentication provider that results in a file path.
1919
- */
1920
- async function filePathRequest(identityClient, requestPrepareOptions) {
1921
- const response = await identityClient.sendRequest(coreRestPipeline.createPipelineRequest(requestPrepareOptions));
1922
- if (response.status !== 401) {
1923
- let message = "";
1924
- if (response.bodyAsText) {
1925
- message = ` Response: ${response.bodyAsText}`;
1857
+ const cache = this.getApp("confidentialFirst", enableCae).getTokenCache();
1858
+ const accountsByTenant = await (cache === null || cache === void 0 ? void 0 : cache.getAllAccounts());
1859
+ if (!accountsByTenant) {
1860
+ return;
1926
1861
  }
1927
- throw new AuthenticationError(response.status, `${msiName$3}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
1928
- }
1929
- const authHeader = response.headers.get("www-authenticate") || "";
1930
- try {
1931
- return authHeader.split("=").slice(1)[0];
1932
- }
1933
- catch (e) {
1934
- throw Error(`Invalid www-authenticate header format: ${authHeader}`);
1862
+ if (accountsByTenant.length === 1) {
1863
+ this.account = msalToPublic(this.clientId, accountsByTenant[0]);
1864
+ }
1865
+ else {
1866
+ this.logger
1867
+ .info(`More than one account was found authenticated for this Client ID and Tenant ID.
1868
+ However, no "authenticationRecord" has been provided for this credential,
1869
+ therefore we're unable to pick between these accounts.
1870
+ A new login attempt will be requested, to ensure the correct account is picked.
1871
+ To work with multiple accounts for the same Client ID and Tenant ID, please provide an "authenticationRecord" when initializing a credential to prevent this from happening.`);
1872
+ return;
1873
+ }
1874
+ return this.account;
1935
1875
  }
1936
- }
1937
- /**
1938
- * Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
1939
- */
1940
- const arcMsi = {
1941
- name: "arc",
1942
- async isAvailable({ scopes }) {
1943
- const resource = mapScopesToResource(scopes);
1944
- if (!resource) {
1945
- logger$j.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
1946
- return false;
1876
+ /**
1877
+ * Attempts to retrieve a token from cache.
1878
+ */
1879
+ async getTokenSilent(scopes, options) {
1880
+ var _a, _b, _c;
1881
+ await this.getActiveAccount(options === null || options === void 0 ? void 0 : options.enableCae);
1882
+ if (!this.account) {
1883
+ throw new AuthenticationRequiredError({
1884
+ scopes,
1885
+ getTokenOptions: options,
1886
+ message: "Silent authentication failed. We couldn't retrieve an active account from the cache.",
1887
+ });
1947
1888
  }
1948
- const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
1949
- if (!result) {
1950
- logger$j.info(`${msiName$3}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
1889
+ const silentRequest = {
1890
+ // To be able to re-use the account, the Token Cache must also have been provided.
1891
+ account: publicToMsal(this.account),
1892
+ correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
1893
+ scopes,
1894
+ authority: options === null || options === void 0 ? void 0 : options.authority,
1895
+ claims: options === null || options === void 0 ? void 0 : options.claims,
1896
+ };
1897
+ if (hasNativeBroker() && this.enableBroker) {
1898
+ if (!silentRequest.tokenQueryParameters) {
1899
+ silentRequest.tokenQueryParameters = {};
1900
+ }
1901
+ if (!this.parentWindowHandle) {
1902
+ // error should have been thrown from within the constructor of InteractiveBrowserCredential
1903
+ this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
1904
+ }
1905
+ if (this.enableMsaPassthrough) {
1906
+ silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
1907
+ }
1951
1908
  }
1952
- return result;
1953
- },
1954
- async getToken(configuration, getTokenOptions = {}) {
1955
- var _a;
1956
- const { identityClient, scopes, clientId, resourceId } = configuration;
1957
- if (clientId) {
1958
- logger$j.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1909
+ try {
1910
+ this.logger.info("Attempting to acquire token silently");
1911
+ /**
1912
+ * The following code to retrieve all accounts is done as a workaround in an attempt to force the
1913
+ * refresh of the token cache with the token and the account passed in through the
1914
+ * `authenticationRecord` parameter. See issue - https://github.com/Azure/azure-sdk-for-js/issues/24349#issuecomment-1496715651
1915
+ * This workaround serves as a workaround for silent authentication not happening when authenticationRecord is passed.
1916
+ */
1917
+ await ((_a = this.getApp("publicFirst", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _a === void 0 ? void 0 : _a.getTokenCache().getAllAccounts());
1918
+ const response = (_c = (await ((_b = this.getApp("confidential", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _b === void 0 ? void 0 : _b.acquireTokenSilent(silentRequest)))) !== null && _c !== void 0 ? _c : (await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenSilent(silentRequest));
1919
+ return this.handleResult(scopes, response || undefined);
1959
1920
  }
1960
- if (resourceId) {
1961
- logger$j.warning(`${msiName$3}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
1921
+ catch (err) {
1922
+ throw handleMsalError(scopes, err, options);
1962
1923
  }
1963
- logger$j.info(`${msiName$3}: Authenticating.`);
1964
- const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), { allowInsecureConnection: true });
1965
- const filePath = await filePathRequest(identityClient, requestOptions);
1966
- if (!filePath) {
1967
- throw new Error(`${msiName$3}: Failed to find the token file.`);
1924
+ }
1925
+ /**
1926
+ * Wrapper around each MSAL flow get token operation: doGetToken.
1927
+ * If disableAutomaticAuthentication is sent through the constructor, it will prevent MSAL from requesting the user input.
1928
+ */
1929
+ async getToken(scopes, options = {}) {
1930
+ const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds) ||
1931
+ this.tenantId;
1932
+ options.authority = getAuthority(tenantId, this.authorityHost);
1933
+ options.correlationId = (options === null || options === void 0 ? void 0 : options.correlationId) || randomUUID();
1934
+ await this.init(options);
1935
+ try {
1936
+ // MSAL now caches tokens based on their claims,
1937
+ // so now one has to keep track fo claims in order to retrieve the newer tokens from acquireTokenSilent
1938
+ // This update happened on PR: https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/4533
1939
+ const optionsClaims = options.claims;
1940
+ if (optionsClaims) {
1941
+ this.cachedClaims = optionsClaims;
1942
+ }
1943
+ if (this.cachedClaims && !optionsClaims) {
1944
+ options.claims = this.cachedClaims;
1945
+ }
1946
+ // We don't return the promise since we want to catch errors right here.
1947
+ return await this.getTokenSilent(scopes, options);
1968
1948
  }
1969
- const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
1970
- (_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
1971
- const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
1972
- // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1973
- allowInsecureConnection: true }));
1974
- const tokenResponse = await identityClient.sendTokenRequest(request);
1975
- return (tokenResponse && tokenResponse.accessToken) || null;
1976
- },
1977
- };
1949
+ catch (err) {
1950
+ if (err.name !== "AuthenticationRequiredError") {
1951
+ throw err;
1952
+ }
1953
+ if (options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication) {
1954
+ throw new AuthenticationRequiredError({
1955
+ scopes,
1956
+ getTokenOptions: options,
1957
+ message: "Automatic authentication has been disabled. You may call the authentication() method.",
1958
+ });
1959
+ }
1960
+ this.logger.info(`Silent authentication failed, falling back to interactive method.`);
1961
+ return this.doGetToken(scopes, options);
1962
+ }
1963
+ }
1964
+ /**
1965
+ * Handles the MSAL authentication result.
1966
+ * If the result has an account, we update the local account reference.
1967
+ * If the token received is invalid, an error will be thrown depending on what's missing.
1968
+ */
1969
+ handleResult(scopes, result, getTokenOptions) {
1970
+ if (result === null || result === void 0 ? void 0 : result.account) {
1971
+ this.account = msalToPublic(this.clientId, result.account);
1972
+ }
1973
+ ensureValidMsalToken(scopes, result, getTokenOptions);
1974
+ this.logger.getToken.info(formatSuccess(scopes));
1975
+ return {
1976
+ token: result.accessToken,
1977
+ expiresOnTimestamp: result.expiresOn.getTime(),
1978
+ };
1979
+ }
1980
+ }
1978
1981
 
1979
1982
  // Copyright (c) Microsoft Corporation.
1980
1983
  // Licensed under the MIT license.