@azure/identity 4.1.0-beta.1 → 4.1.1-alpha.20240411.2

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.

Files changed (49) hide show
  1. package/dist/index.js +1473 -1396
  2. package/dist/index.js.map +1 -1
  3. package/dist-esm/src/constants.js +10 -3
  4. package/dist-esm/src/constants.js.map +1 -1
  5. package/dist-esm/src/credentials/authorizationCodeCredential.js +1 -1
  6. package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
  7. package/dist-esm/src/credentials/azureDeveloperCliCredential.js +1 -1
  8. package/dist-esm/src/credentials/azureDeveloperCliCredential.js.map +1 -1
  9. package/dist-esm/src/credentials/clientAssertionCredential.js.map +1 -1
  10. package/dist-esm/src/credentials/clientSecretCredential.js +1 -1
  11. package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
  12. package/dist-esm/src/credentials/defaultAzureCredential.js +9 -5
  13. package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
  14. package/dist-esm/src/credentials/interactiveBrowserCredential.js +4 -3
  15. package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
  16. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +10 -16
  17. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
  18. package/dist-esm/src/credentials/managedIdentityCredential/index.js +22 -14
  19. package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
  20. package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -1
  21. package/dist-esm/src/credentials/onBehalfOfCredential.browser.js +1 -1
  22. package/dist-esm/src/credentials/onBehalfOfCredential.browser.js.map +1 -1
  23. package/dist-esm/src/credentials/onBehalfOfCredential.js +1 -1
  24. package/dist-esm/src/credentials/onBehalfOfCredential.js.map +1 -1
  25. package/dist-esm/src/msal/browserFlows/msalBrowserCommon.js.map +1 -1
  26. package/dist-esm/src/msal/msal.browser.js +5 -0
  27. package/dist-esm/src/msal/msal.browser.js.map +1 -0
  28. package/dist-esm/src/msal/msal.js +5 -0
  29. package/dist-esm/src/msal/msal.js.map +1 -0
  30. package/dist-esm/src/msal/nodeFlows/brokerOptions.js.map +1 -1
  31. package/dist-esm/src/msal/nodeFlows/msalClient.js +170 -0
  32. package/dist-esm/src/msal/nodeFlows/msalClient.js.map +1 -0
  33. package/dist-esm/src/msal/nodeFlows/msalNodeCommon.js +8 -42
  34. package/dist-esm/src/msal/nodeFlows/msalNodeCommon.js.map +1 -1
  35. package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js +60 -18
  36. package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js.map +1 -1
  37. package/dist-esm/src/msal/nodeFlows/msalPlugins.js +86 -0
  38. package/dist-esm/src/msal/nodeFlows/msalPlugins.js.map +1 -0
  39. package/dist-esm/src/msal/types.js.map +1 -1
  40. package/dist-esm/src/msal/utils.js +1 -1
  41. package/dist-esm/src/msal/utils.js.map +1 -1
  42. package/dist-esm/src/plugins/consumer.js +1 -1
  43. package/dist-esm/src/plugins/consumer.js.map +1 -1
  44. package/dist-esm/src/regionalAuthority.js +21 -0
  45. package/dist-esm/src/regionalAuthority.js.map +1 -1
  46. package/package.json +14 -14
  47. package/types/identity.d.ts +20 -11
  48. package/dist-esm/src/msal/utils.browser.js +0 -204
  49. package/dist-esm/src/msal/utils.browser.js.map +0 -1
package/dist/index.js CHANGED
@@ -2,18 +2,18 @@
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');
15
- var promises = require('fs/promises');
14
+ var msalCommon = require('@azure/msal-node');
16
15
  var https = require('https');
16
+ var promises = require('fs/promises');
17
17
  var child_process = require('child_process');
18
18
  var crypto = require('crypto');
19
19
  var util = require('util');
@@ -44,7 +44,7 @@ var child_process__namespace = /*#__PURE__*/_interopNamespaceDefault(child_proce
44
44
  /**
45
45
  * Current version of the `@azure/identity` package.
46
46
  */
47
- const SDK_VERSION = `4.1.0-beta.1`;
47
+ const SDK_VERSION = `4.1.1`;
48
48
  /**
49
49
  * The default client ID for authentication
50
50
  * @internal
@@ -93,11 +93,54 @@ const ALL_TENANTS = ["*"];
93
93
  /**
94
94
  * @internal
95
95
  */
96
- const CACHE_CAE_SUFFIX = ".cae";
96
+ const CACHE_CAE_SUFFIX = "cae";
97
+ /**
98
+ * @internal
99
+ */
100
+ const CACHE_NON_CAE_SUFFIX = "nocae";
101
+ /**
102
+ * @internal
103
+ *
104
+ * The default name for the cache persistence plugin.
105
+ * Matches the constant defined in the cache persistence package.
106
+ */
107
+ const DEFAULT_TOKEN_CACHE_NAME = "msal.cache";
108
+
109
+ // Copyright (c) Microsoft Corporation.
110
+ // Licensed under the MIT license.
111
+ /**
112
+ * The current persistence provider, undefined by default.
113
+ * @internal
114
+ */
115
+ let persistenceProvider = undefined;
116
+ /**
117
+ * An object that allows setting the persistence provider.
118
+ * @internal
119
+ */
120
+ const msalNodeFlowCacheControl = {
121
+ setPersistence(pluginProvider) {
122
+ persistenceProvider = pluginProvider;
123
+ },
124
+ };
125
+ /**
126
+ * The current native broker provider, undefined by default.
127
+ * @internal
128
+ */
129
+ let nativeBrokerInfo = undefined;
130
+ function hasNativeBroker() {
131
+ return nativeBrokerInfo !== undefined;
132
+ }
97
133
  /**
134
+ * An object that allows setting the native broker provider.
98
135
  * @internal
99
136
  */
100
- const CACHE_NON_CAE_SUFFIX = ".nocae";
137
+ const msalNodeFlowNativeBrokerControl = {
138
+ setNativeBroker(broker) {
139
+ nativeBrokerInfo = {
140
+ broker,
141
+ };
142
+ },
143
+ };
101
144
 
102
145
  // Copyright (c) Microsoft Corporation.
103
146
  // Licensed under the MIT license.
@@ -297,218 +340,6 @@ class AuthenticationRequiredError extends Error {
297
340
  }
298
341
  }
299
342
 
300
- // Copyright (c) Microsoft Corporation.
301
- // Licensed under the MIT license.
302
- /**
303
- * @internal
304
- */
305
- const logger$o = credentialLogger("IdentityUtils");
306
- /**
307
- * Latest AuthenticationRecord version
308
- * @internal
309
- */
310
- const LatestAuthenticationRecordVersion = "1.0";
311
- /**
312
- * Ensures the validity of the MSAL token
313
- * @internal
314
- */
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");
326
- }
327
- if (!msalToken.expiresOn) {
328
- throw error(`Response had no "expiresOn" property.`);
329
- }
330
- if (!msalToken.accessToken) {
331
- throw error(`Response had no "accessToken" property.`);
332
- }
333
- }
334
- /**
335
- * Generates a valid authority by combining a host with a tenantId.
336
- * @internal
337
- */
338
- function getAuthority(tenantId, host) {
339
- if (!host) {
340
- host = DefaultAuthorityHost;
341
- }
342
- if (new RegExp(`${tenantId}/?$`).test(host)) {
343
- return host;
344
- }
345
- if (host.endsWith("/")) {
346
- return host + tenantId;
347
- }
348
- else {
349
- return `${host}/${tenantId}`;
350
- }
351
- }
352
- /**
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.
357
- * @internal
358
- */
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
343
  // Copyright (c) Microsoft Corporation.
513
344
  // Licensed under the MIT license.
514
345
  function createConfigurationErrorMessage(tenantId) {
@@ -899,1082 +730,1432 @@ class IdentityClient extends coreClient.ServiceClient {
899
730
 
900
731
  // Copyright (c) Microsoft Corporation.
901
732
  // 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;
733
+ const CommonTenantId = "common";
734
+ const AzureAccountClientId = "aebc6443-996d-45c2-90f0-388ff96faa56"; // VSC: 'aebc6443-996d-45c2-90f0-388ff96faa56'
735
+ const logger$o = credentialLogger("VisualStudioCodeCredential");
736
+ let findCredentials = undefined;
737
+ const vsCodeCredentialControl = {
738
+ setVsCodeCredentialFinder(finder) {
739
+ findCredentials = finder;
1029
740
  },
1030
741
  };
1031
- /**
1032
- * The current native broker provider, undefined by default.
1033
- * @internal
1034
- */
1035
- let nativeBrokerInfo = undefined;
1036
- function hasNativeBroker() {
1037
- return nativeBrokerInfo !== undefined;
742
+ // Map of unsupported Tenant IDs and the errors we will be throwing.
743
+ const unsupportedTenantIds = {
744
+ adfs: "The VisualStudioCodeCredential does not support authentication with ADFS tenants.",
745
+ };
746
+ function checkUnsupportedTenant(tenantId) {
747
+ // If the Tenant ID isn't supported, we throw.
748
+ const unsupportedTenantError = unsupportedTenantIds[tenantId];
749
+ if (unsupportedTenantError) {
750
+ throw new CredentialUnavailableError(unsupportedTenantError);
751
+ }
1038
752
  }
753
+ const mapVSCodeAuthorityHosts = {
754
+ AzureCloud: exports.AzureAuthorityHosts.AzurePublicCloud,
755
+ AzureChina: exports.AzureAuthorityHosts.AzureChina,
756
+ AzureGermanCloud: exports.AzureAuthorityHosts.AzureGermany,
757
+ AzureUSGovernment: exports.AzureAuthorityHosts.AzureGovernment,
758
+ };
1039
759
  /**
1040
- * An object that allows setting the native broker provider.
1041
- * @internal
760
+ * Attempts to load a specific property from the VSCode configurations of the current OS.
761
+ * If it fails at any point, returns undefined.
1042
762
  */
1043
- const msalNodeFlowNativeBrokerControl = {
1044
- setNativeBroker(broker) {
1045
- nativeBrokerInfo = {
1046
- broker,
1047
- };
1048
- },
1049
- };
763
+ function getPropertyFromVSCode(property) {
764
+ const settingsPath = ["User", "settings.json"];
765
+ // Eventually we can add more folders for more versions of VSCode.
766
+ const vsCodeFolder = "Code";
767
+ const homedir = os.homedir();
768
+ function loadProperty(...pathSegments) {
769
+ const fullPath = path.join(...pathSegments, vsCodeFolder, ...settingsPath);
770
+ const settings = JSON.parse(fs.readFileSync(fullPath, { encoding: "utf8" }));
771
+ return settings[property];
772
+ }
773
+ try {
774
+ let appData;
775
+ switch (process.platform) {
776
+ case "win32":
777
+ appData = process.env.APPDATA;
778
+ return appData ? loadProperty(appData) : undefined;
779
+ case "darwin":
780
+ return loadProperty(homedir, "Library", "Application Support");
781
+ case "linux":
782
+ return loadProperty(homedir, ".config");
783
+ default:
784
+ return;
785
+ }
786
+ }
787
+ catch (e) {
788
+ logger$o.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);
789
+ return;
790
+ }
791
+ }
1050
792
  /**
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.
793
+ * Connects to Azure using the credential provided by the VSCode extension 'Azure Account'.
794
+ * Once the user has logged in via the extension, this credential can share the same refresh token
795
+ * that is cached by the extension.
1056
796
  *
1057
- * @internal
797
+ * It's a [known issue](https://github.com/Azure/azure-sdk-for-js/issues/20500) that this credential doesn't
798
+ * work with [Azure Account extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account)
799
+ * versions newer than **0.9.11**. A long-term fix to this problem is in progress. In the meantime, consider
800
+ * authenticating with {@link AzureCliCredential}.
1058
801
  */
1059
- class MsalNode {
802
+ class VisualStudioCodeCredential {
803
+ /**
804
+ * Creates an instance of VisualStudioCodeCredential to use for automatically authenticating via VSCode.
805
+ *
806
+ * **Note**: `VisualStudioCodeCredential` is provided by a plugin package:
807
+ * `@azure/identity-vscode`. If this package is not installed and registered
808
+ * using the plugin API (`useIdentityPlugin`), then authentication using
809
+ * `VisualStudioCodeCredential` will not be available.
810
+ *
811
+ * @param options - Options for configuring the client which makes the authentication request.
812
+ */
1060
813
  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);
814
+ // We want to make sure we use the one assigned by the user on the VSCode settings.
815
+ // Or just `AzureCloud` by default.
816
+ this.cloudName = (getPropertyFromVSCode("azure.cloud") || "AzureCloud");
817
+ // Picking an authority host based on the cloud name.
818
+ const authorityHost = mapVSCodeAuthorityHosts[this.cloudName];
819
+ this.identityClient = new IdentityClient(Object.assign({ authorityHost }, options));
820
+ if (options && options.tenantId) {
821
+ checkTenantId(logger$o, options.tenantId);
822
+ this.tenantId = options.tenantId;
1082
823
  }
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(" "));
1099
- }
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";
824
+ else {
825
+ this.tenantId = CommonTenantId;
1103
826
  }
827
+ this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
828
+ checkUnsupportedTenant(this.tenantId);
1104
829
  }
1105
830
  /**
1106
- * Generates a MSAL configuration that generally works for Node.js
831
+ * Runs preparations for any further getToken request.
1107
832
  */
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;
833
+ async prepare() {
834
+ // Attempts to load the tenant from the VSCode configuration file.
835
+ const settingsTenant = getPropertyFromVSCode("azure.tenant");
836
+ if (settingsTenant) {
837
+ this.tenantId = settingsTenant;
1147
838
  }
839
+ checkUnsupportedTenant(this.tenantId);
1148
840
  }
1149
841
  /**
1150
- * Prepares the MSAL applications.
842
+ * Runs preparations for any further getToken, but only once.
1151
843
  */
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"];
1163
- }
1164
- if (app.public || app.confidential) {
1165
- return;
1166
- }
1167
- if ((options === null || options === void 0 ? void 0 : options.enableCae) && this.createCachePluginCae !== undefined) {
1168
- this.msalConfig.cache = {
1169
- cachePlugin: await this.createCachePluginCae(),
1170
- };
1171
- }
1172
- if (this.createCachePlugin !== undefined) {
1173
- this.msalConfig.cache = {
1174
- cachePlugin: await this.createCachePlugin(),
1175
- };
1176
- }
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.");
1184
- }
1185
- }
1186
- if (options === null || options === void 0 ? void 0 : options.enableCae) {
1187
- this.caeApp.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
1188
- }
1189
- else {
1190
- this.app.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
1191
- }
1192
- if (this.getAssertion) {
1193
- this.msalConfig.auth.clientAssertion = await this.getAssertion();
1194
- }
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
- }
1205
- }
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
- }
844
+ prepareOnce() {
845
+ if (!this.preparePromise) {
846
+ this.preparePromise = this.prepare();
1210
847
  }
848
+ return this.preparePromise;
1211
849
  }
1212
850
  /**
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
- });
1228
- }
1229
- /**
1230
- * Returns the existing account, attempts to load the account from MSAL.
851
+ * Returns the token found by searching VSCode's authentication cache or
852
+ * returns null if no token could be found.
853
+ *
854
+ * @param scopes - The list of scopes for which the token will have access.
855
+ * @param options - The options used to configure any requests this
856
+ * `TokenCredential` implementation might make.
1231
857
  */
1232
- async getActiveAccount(enableCae = false) {
1233
- if (this.account) {
1234
- return this.account;
1235
- }
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;
1240
- }
1241
- if (accountsByTenant.length === 1) {
1242
- this.account = msalToPublic(this.clientId, accountsByTenant[0]);
858
+ async getToken(scopes, options) {
859
+ var _a, _b;
860
+ await this.prepareOnce();
861
+ const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds, logger$o) || this.tenantId;
862
+ if (findCredentials === undefined) {
863
+ throw new CredentialUnavailableError([
864
+ "No implementation of `VisualStudioCodeCredential` is available.",
865
+ "You must install the identity-vscode plugin package (`npm install --save-dev @azure/identity-vscode`)",
866
+ "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
867
+ "`useIdentityPlugin(vsCodePlugin)` before creating a `VisualStudioCodeCredential`.",
868
+ "To troubleshoot, visit https://aka.ms/azsdk/js/identity/vscodecredential/troubleshoot.",
869
+ ].join(" "));
1243
870
  }
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;
871
+ let scopeString = typeof scopes === "string" ? scopes : scopes.join(" ");
872
+ // Check to make sure the scope we get back is a valid scope
873
+ if (!scopeString.match(/^[0-9a-zA-Z-.:/]+$/)) {
874
+ const error = new Error("Invalid scope was specified by the user or calling client");
875
+ logger$o.getToken.info(formatError(scopes, error));
876
+ throw error;
1252
877
  }
1253
- return this.account;
1254
- }
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
- });
878
+ if (scopeString.indexOf("offline_access") < 0) {
879
+ scopeString += " offline_access";
1267
880
  }
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,
1275
- };
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.");
881
+ // findCredentials returns an array similar to:
882
+ // [
883
+ // {
884
+ // account: "",
885
+ // password: "",
886
+ // },
887
+ // /* ... */
888
+ // ]
889
+ const credentials = await findCredentials();
890
+ // If we can't find the credential based on the name, we'll pick the first one available.
891
+ const { password: refreshToken } = (_b = (_a = credentials.find(({ account }) => account === this.cloudName)) !== null && _a !== void 0 ? _a : credentials[0]) !== null && _b !== void 0 ? _b : {};
892
+ if (refreshToken) {
893
+ const tokenResponse = await this.identityClient.refreshAccessToken(tenantId, AzureAccountClientId, scopeString, refreshToken, undefined);
894
+ if (tokenResponse) {
895
+ logger$o.getToken.info(formatSuccess(scopes));
896
+ return tokenResponse.accessToken;
1283
897
  }
1284
- if (this.enableMsaPassthrough) {
1285
- silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
898
+ else {
899
+ 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.");
900
+ logger$o.getToken.info(formatError(scopes, error));
901
+ throw error;
1286
902
  }
1287
903
  }
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);
1299
- }
1300
- catch (err) {
1301
- throw handleMsalError(scopes, err, options);
904
+ else {
905
+ 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.");
906
+ logger$o.getToken.info(formatError(scopes, error));
907
+ throw error;
1302
908
  }
1303
909
  }
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;
1321
- }
1322
- if (this.cachedClaims && !optionsClaims) {
1323
- options.claims = this.cachedClaims;
1324
- }
1325
- // We don't return the promise since we want to catch errors right here.
1326
- return await this.getTokenSilent(scopes, options);
910
+ }
911
+
912
+ // Copyright (c) Microsoft Corporation.
913
+ // Licensed under the MIT license.
914
+ /**
915
+ * The context passed to an Identity plugin. This contains objects that
916
+ * plugins can use to set backend implementations.
917
+ * @internal
918
+ */
919
+ const pluginContext = {
920
+ cachePluginControl: msalNodeFlowCacheControl,
921
+ nativeBrokerPluginControl: msalNodeFlowNativeBrokerControl,
922
+ vsCodeCredentialControl: vsCodeCredentialControl,
923
+ };
924
+ /**
925
+ * Extend Azure Identity with additional functionality. Pass a plugin from
926
+ * a plugin package, such as:
927
+ *
928
+ * - `@azure/identity-cache-persistence`: provides persistent token caching
929
+ * - `@azure/identity-vscode`: provides the dependencies of
930
+ * `VisualStudioCodeCredential` and enables it
931
+ *
932
+ * Example:
933
+ *
934
+ * ```javascript
935
+ * import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
936
+ *
937
+ * import { useIdentityPlugin, DefaultAzureCredential } from "@azure/identity";
938
+ * useIdentityPlugin(cachePersistencePlugin);
939
+ *
940
+ * // The plugin has the capability to extend `DefaultAzureCredential` and to
941
+ * // add middleware to the underlying credentials, such as persistence.
942
+ * const credential = new DefaultAzureCredential({
943
+ * tokenCachePersistenceOptions: {
944
+ * enabled: true
945
+ * }
946
+ * });
947
+ * ```
948
+ *
949
+ * @param plugin - the plugin to register
950
+ */
951
+ function useIdentityPlugin(plugin) {
952
+ plugin(pluginContext);
953
+ }
954
+
955
+ // Copyright (c) Microsoft Corporation.
956
+ // Licensed under the MIT license.
957
+ const msiName$6 = "ManagedIdentityCredential - AppServiceMSI 2017";
958
+ const logger$n = credentialLogger(msiName$6);
959
+ /**
960
+ * Generates the options used on the request for an access token.
961
+ */
962
+ function prepareRequestOptions$5(scopes, clientId) {
963
+ const resource = mapScopesToResource(scopes);
964
+ if (!resource) {
965
+ throw new Error(`${msiName$6}: Multiple scopes are not supported.`);
966
+ }
967
+ const queryParameters = {
968
+ resource,
969
+ "api-version": "2017-09-01",
970
+ };
971
+ if (clientId) {
972
+ queryParameters.clientid = clientId;
973
+ }
974
+ const query = new URLSearchParams(queryParameters);
975
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
976
+ if (!process.env.MSI_ENDPOINT) {
977
+ throw new Error(`${msiName$6}: Missing environment variable: MSI_ENDPOINT`);
978
+ }
979
+ if (!process.env.MSI_SECRET) {
980
+ throw new Error(`${msiName$6}: Missing environment variable: MSI_SECRET`);
981
+ }
982
+ return {
983
+ url: `${process.env.MSI_ENDPOINT}?${query.toString()}`,
984
+ method: "GET",
985
+ headers: coreRestPipeline.createHttpHeaders({
986
+ Accept: "application/json",
987
+ secret: process.env.MSI_SECRET,
988
+ }),
989
+ };
990
+ }
991
+ /**
992
+ * 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.
993
+ */
994
+ const appServiceMsi2017 = {
995
+ name: "appServiceMsi2017",
996
+ async isAvailable({ scopes }) {
997
+ const resource = mapScopesToResource(scopes);
998
+ if (!resource) {
999
+ logger$n.info(`${msiName$6}: Unavailable. Multiple scopes are not supported.`);
1000
+ return false;
1001
+ }
1002
+ const env = process.env;
1003
+ const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
1004
+ if (!result) {
1005
+ logger$n.info(`${msiName$6}: Unavailable. The environment variables needed are: MSI_ENDPOINT and MSI_SECRET.`);
1006
+ }
1007
+ return result;
1008
+ },
1009
+ async getToken(configuration, getTokenOptions = {}) {
1010
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1011
+ if (resourceId) {
1012
+ logger$n.warning(`${msiName$6}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
1013
+ }
1014
+ 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].`);
1015
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId)), {
1016
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1017
+ allowInsecureConnection: true }));
1018
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1019
+ return (tokenResponse && tokenResponse.accessToken) || null;
1020
+ },
1021
+ };
1022
+
1023
+ // Copyright (c) Microsoft Corporation.
1024
+ // Licensed under the MIT license.
1025
+ const msiName$5 = "ManagedIdentityCredential - AppServiceMSI 2019";
1026
+ const logger$m = credentialLogger(msiName$5);
1027
+ /**
1028
+ * Generates the options used on the request for an access token.
1029
+ */
1030
+ function prepareRequestOptions$4(scopes, clientId, resourceId) {
1031
+ const resource = mapScopesToResource(scopes);
1032
+ if (!resource) {
1033
+ throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
1034
+ }
1035
+ const queryParameters = {
1036
+ resource,
1037
+ "api-version": "2019-08-01",
1038
+ };
1039
+ if (clientId) {
1040
+ queryParameters.client_id = clientId;
1041
+ }
1042
+ if (resourceId) {
1043
+ queryParameters.mi_res_id = resourceId;
1044
+ }
1045
+ const query = new URLSearchParams(queryParameters);
1046
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1047
+ if (!process.env.IDENTITY_ENDPOINT) {
1048
+ throw new Error(`${msiName$5}: Missing environment variable: IDENTITY_ENDPOINT`);
1049
+ }
1050
+ if (!process.env.IDENTITY_HEADER) {
1051
+ throw new Error(`${msiName$5}: Missing environment variable: IDENTITY_HEADER`);
1052
+ }
1053
+ return {
1054
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
1055
+ method: "GET",
1056
+ headers: coreRestPipeline.createHttpHeaders({
1057
+ Accept: "application/json",
1058
+ "X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
1059
+ }),
1060
+ };
1061
+ }
1062
+ /**
1063
+ * 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.
1064
+ */
1065
+ const appServiceMsi2019 = {
1066
+ name: "appServiceMsi2019",
1067
+ async isAvailable({ scopes }) {
1068
+ const resource = mapScopesToResource(scopes);
1069
+ if (!resource) {
1070
+ logger$m.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
1071
+ return false;
1072
+ }
1073
+ const env = process.env;
1074
+ const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
1075
+ if (!result) {
1076
+ logger$m.info(`${msiName$5}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
1077
+ }
1078
+ return result;
1079
+ },
1080
+ async getToken(configuration, getTokenOptions = {}) {
1081
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1082
+ logger$m.info(`${msiName$5}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
1083
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
1084
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1085
+ allowInsecureConnection: true }));
1086
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1087
+ return (tokenResponse && tokenResponse.accessToken) || null;
1088
+ },
1089
+ };
1090
+
1091
+ // Copyright (c) Microsoft Corporation.
1092
+ // Licensed under the MIT license.
1093
+ const msiName$4 = "ManagedIdentityCredential - Azure Arc MSI";
1094
+ const logger$l = credentialLogger(msiName$4);
1095
+ /**
1096
+ * Generates the options used on the request for an access token.
1097
+ */
1098
+ function prepareRequestOptions$3(scopes, clientId, resourceId) {
1099
+ const resource = mapScopesToResource(scopes);
1100
+ if (!resource) {
1101
+ throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
1102
+ }
1103
+ const queryParameters = {
1104
+ resource,
1105
+ "api-version": azureArcAPIVersion,
1106
+ };
1107
+ if (clientId) {
1108
+ queryParameters.client_id = clientId;
1109
+ }
1110
+ if (resourceId) {
1111
+ queryParameters.msi_res_id = resourceId;
1112
+ }
1113
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1114
+ if (!process.env.IDENTITY_ENDPOINT) {
1115
+ throw new Error(`${msiName$4}: Missing environment variable: IDENTITY_ENDPOINT`);
1116
+ }
1117
+ const query = new URLSearchParams(queryParameters);
1118
+ return coreRestPipeline.createPipelineRequest({
1119
+ // Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
1120
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
1121
+ method: "GET",
1122
+ headers: coreRestPipeline.createHttpHeaders({
1123
+ Accept: "application/json",
1124
+ Metadata: "true",
1125
+ }),
1126
+ });
1127
+ }
1128
+ /**
1129
+ * Retrieves the file contents at the given path using promises.
1130
+ * Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
1131
+ */
1132
+ function readFileAsync$1(path, options) {
1133
+ return new Promise((resolve, reject) => fs.readFile(path, options, (err, data) => {
1134
+ if (err) {
1135
+ reject(err);
1136
+ }
1137
+ resolve(data);
1138
+ }));
1139
+ }
1140
+ /**
1141
+ * Does a request to the authentication provider that results in a file path.
1142
+ */
1143
+ async function filePathRequest(identityClient, requestPrepareOptions) {
1144
+ const response = await identityClient.sendRequest(coreRestPipeline.createPipelineRequest(requestPrepareOptions));
1145
+ if (response.status !== 401) {
1146
+ let message = "";
1147
+ if (response.bodyAsText) {
1148
+ message = ` Response: ${response.bodyAsText}`;
1149
+ }
1150
+ throw new AuthenticationError(response.status, `${msiName$4}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
1151
+ }
1152
+ const authHeader = response.headers.get("www-authenticate") || "";
1153
+ try {
1154
+ return authHeader.split("=").slice(1)[0];
1155
+ }
1156
+ catch (e) {
1157
+ throw Error(`Invalid www-authenticate header format: ${authHeader}`);
1158
+ }
1159
+ }
1160
+ /**
1161
+ * Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
1162
+ */
1163
+ const arcMsi = {
1164
+ name: "arc",
1165
+ async isAvailable({ scopes }) {
1166
+ const resource = mapScopesToResource(scopes);
1167
+ if (!resource) {
1168
+ logger$l.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
1169
+ return false;
1170
+ }
1171
+ const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
1172
+ if (!result) {
1173
+ logger$l.info(`${msiName$4}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
1174
+ }
1175
+ return result;
1176
+ },
1177
+ async getToken(configuration, getTokenOptions = {}) {
1178
+ var _a;
1179
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1180
+ if (clientId) {
1181
+ logger$l.warning(`${msiName$4}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1182
+ }
1183
+ if (resourceId) {
1184
+ logger$l.warning(`${msiName$4}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
1185
+ }
1186
+ logger$l.info(`${msiName$4}: Authenticating.`);
1187
+ const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true });
1188
+ const filePath = await filePathRequest(identityClient, requestOptions);
1189
+ if (!filePath) {
1190
+ throw new Error(`${msiName$4}: Failed to find the token file.`);
1191
+ }
1192
+ const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
1193
+ (_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
1194
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
1195
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1196
+ allowInsecureConnection: true }));
1197
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1198
+ return (tokenResponse && tokenResponse.accessToken) || null;
1199
+ },
1200
+ };
1201
+
1202
+ // Copyright (c) Microsoft Corporation.
1203
+ // Licensed under the MIT license.
1204
+ const msiName$3 = "ManagedIdentityCredential - CloudShellMSI";
1205
+ const logger$k = credentialLogger(msiName$3);
1206
+ /**
1207
+ * Generates the options used on the request for an access token.
1208
+ */
1209
+ function prepareRequestOptions$2(scopes, clientId, resourceId) {
1210
+ const resource = mapScopesToResource(scopes);
1211
+ if (!resource) {
1212
+ throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
1213
+ }
1214
+ const body = {
1215
+ resource,
1216
+ };
1217
+ if (clientId) {
1218
+ body.client_id = clientId;
1219
+ }
1220
+ if (resourceId) {
1221
+ body.msi_res_id = resourceId;
1222
+ }
1223
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1224
+ if (!process.env.MSI_ENDPOINT) {
1225
+ throw new Error(`${msiName$3}: Missing environment variable: MSI_ENDPOINT`);
1226
+ }
1227
+ const params = new URLSearchParams(body);
1228
+ return {
1229
+ url: process.env.MSI_ENDPOINT,
1230
+ method: "POST",
1231
+ body: params.toString(),
1232
+ headers: coreRestPipeline.createHttpHeaders({
1233
+ Accept: "application/json",
1234
+ Metadata: "true",
1235
+ "Content-Type": "application/x-www-form-urlencoded",
1236
+ }),
1237
+ };
1238
+ }
1239
+ /**
1240
+ * 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.
1241
+ * 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.
1242
+ */
1243
+ const cloudShellMsi = {
1244
+ name: "cloudShellMsi",
1245
+ async isAvailable({ scopes }) {
1246
+ const resource = mapScopesToResource(scopes);
1247
+ if (!resource) {
1248
+ logger$k.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
1249
+ return false;
1327
1250
  }
1328
- catch (err) {
1329
- if (err.name !== "AuthenticationRequiredError") {
1330
- throw err;
1331
- }
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
- });
1338
- }
1339
- this.logger.info(`Silent authentication failed, falling back to interactive method.`);
1340
- return this.doGetToken(scopes, options);
1251
+ const result = Boolean(process.env.MSI_ENDPOINT);
1252
+ if (!result) {
1253
+ logger$k.info(`${msiName$3}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
1254
+ }
1255
+ return result;
1256
+ },
1257
+ async getToken(configuration, getTokenOptions = {}) {
1258
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1259
+ if (clientId) {
1260
+ logger$k.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1341
1261
  }
1262
+ if (resourceId) {
1263
+ logger$k.warning(`${msiName$3}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
1264
+ }
1265
+ logger$k.info(`${msiName$3}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
1266
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), {
1267
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1268
+ allowInsecureConnection: true }));
1269
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1270
+ return (tokenResponse && tokenResponse.accessToken) || null;
1271
+ },
1272
+ };
1273
+
1274
+ // Copyright (c) Microsoft Corporation.
1275
+ // Licensed under the MIT license.
1276
+ // This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
1277
+ //
1278
+ // FROM node:12
1279
+ // RUN wget https://host.any/path/bash.sh
1280
+ // CMD ["bash", "bash.sh"]
1281
+ //
1282
+ // Where the bash script contains:
1283
+ //
1284
+ // curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
1285
+ //
1286
+ const msiName$2 = "ManagedIdentityCredential - Fabric MSI";
1287
+ const logger$j = credentialLogger(msiName$2);
1288
+ /**
1289
+ * Generates the options used on the request for an access token.
1290
+ */
1291
+ function prepareRequestOptions$1(scopes, clientId, resourceId) {
1292
+ const resource = mapScopesToResource(scopes);
1293
+ if (!resource) {
1294
+ throw new Error(`${msiName$2}: Multiple scopes are not supported.`);
1342
1295
  }
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);
1296
+ const queryParameters = {
1297
+ resource,
1298
+ "api-version": azureFabricVersion,
1299
+ };
1300
+ if (clientId) {
1301
+ queryParameters.client_id = clientId;
1302
+ }
1303
+ if (resourceId) {
1304
+ queryParameters.msi_res_id = resourceId;
1305
+ }
1306
+ const query = new URLSearchParams(queryParameters);
1307
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1308
+ if (!process.env.IDENTITY_ENDPOINT) {
1309
+ throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
1310
+ }
1311
+ if (!process.env.IDENTITY_HEADER) {
1312
+ throw new Error("Missing environment variable: IDENTITY_HEADER");
1313
+ }
1314
+ return {
1315
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
1316
+ method: "GET",
1317
+ headers: coreRestPipeline.createHttpHeaders({
1318
+ Accept: "application/json",
1319
+ secret: process.env.IDENTITY_HEADER,
1320
+ }),
1321
+ };
1322
+ }
1323
+ /**
1324
+ * Defines how to determine whether the Azure Service Fabric MSI is available, and also how to retrieve a token from the Azure Service Fabric MSI.
1325
+ */
1326
+ const fabricMsi = {
1327
+ name: "fabricMsi",
1328
+ async isAvailable({ scopes }) {
1329
+ const resource = mapScopesToResource(scopes);
1330
+ if (!resource) {
1331
+ logger$j.info(`${msiName$2}: Unavailable. Multiple scopes are not supported.`);
1332
+ return false;
1351
1333
  }
1352
- ensureValidMsalToken(scopes, result, getTokenOptions);
1353
- this.logger.getToken.info(formatSuccess(scopes));
1354
- return {
1355
- token: result.accessToken,
1356
- expiresOnTimestamp: result.expiresOn.getTime(),
1357
- };
1334
+ const env = process.env;
1335
+ const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
1336
+ if (!result) {
1337
+ logger$j.info(`${msiName$2}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
1338
+ }
1339
+ return result;
1340
+ },
1341
+ async getToken(configuration, getTokenOptions = {}) {
1342
+ const { scopes, identityClient, clientId, resourceId } = configuration;
1343
+ if (resourceId) {
1344
+ logger$j.warning(`${msiName$2}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
1345
+ }
1346
+ logger$j.info([
1347
+ `${msiName$2}:`,
1348
+ "Using the endpoint and the secret coming from the environment variables:",
1349
+ `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
1350
+ "IDENTITY_HEADER=[REDACTED] and",
1351
+ "IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
1352
+ ].join(" "));
1353
+ const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
1354
+ request.agent = new https.Agent({
1355
+ // This is necessary because Service Fabric provides a self-signed certificate.
1356
+ // The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
1357
+ rejectUnauthorized: false,
1358
+ });
1359
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1360
+ return (tokenResponse && tokenResponse.accessToken) || null;
1361
+ },
1362
+ };
1363
+
1364
+ // Copyright (c) Microsoft Corporation.
1365
+ // Licensed under the MIT license.
1366
+ /**
1367
+ * @internal
1368
+ */
1369
+ const logger$i = credentialLogger("IdentityUtils");
1370
+ /**
1371
+ * Latest AuthenticationRecord version
1372
+ * @internal
1373
+ */
1374
+ const LatestAuthenticationRecordVersion = "1.0";
1375
+ /**
1376
+ * Ensures the validity of the MSAL token
1377
+ * @internal
1378
+ */
1379
+ function ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
1380
+ const error = (message) => {
1381
+ logger$i.getToken.info(message);
1382
+ return new AuthenticationRequiredError({
1383
+ scopes: Array.isArray(scopes) ? scopes : [scopes],
1384
+ getTokenOptions,
1385
+ message,
1386
+ });
1387
+ };
1388
+ if (!msalToken) {
1389
+ throw error("No response");
1390
+ }
1391
+ if (!msalToken.expiresOn) {
1392
+ throw error(`Response had no "expiresOn" property.`);
1393
+ }
1394
+ if (!msalToken.accessToken) {
1395
+ throw error(`Response had no "accessToken" property.`);
1396
+ }
1397
+ }
1398
+ /**
1399
+ * Generates a valid authority by combining a host with a tenantId.
1400
+ * @internal
1401
+ */
1402
+ function getAuthority(tenantId, host) {
1403
+ if (!host) {
1404
+ host = DefaultAuthorityHost;
1405
+ }
1406
+ if (new RegExp(`${tenantId}/?$`).test(host)) {
1407
+ return host;
1408
+ }
1409
+ if (host.endsWith("/")) {
1410
+ return host + tenantId;
1411
+ }
1412
+ else {
1413
+ return `${host}/${tenantId}`;
1414
+ }
1415
+ }
1416
+ /**
1417
+ * Generates the known authorities.
1418
+ * If the Tenant Id is `adfs`, the authority can't be validated since the format won't match the expected one.
1419
+ * For that reason, we have to force MSAL to disable validating the authority
1420
+ * by sending it within the known authorities in the MSAL configuration.
1421
+ * @internal
1422
+ */
1423
+ function getKnownAuthorities(tenantId, authorityHost, disableInstanceDiscovery) {
1424
+ if ((tenantId === "adfs" && authorityHost) || disableInstanceDiscovery) {
1425
+ return [authorityHost];
1426
+ }
1427
+ return [];
1428
+ }
1429
+ /**
1430
+ * Generates a logger that can be passed to the MSAL clients.
1431
+ * @param credLogger - The logger of the credential.
1432
+ * @internal
1433
+ */
1434
+ const defaultLoggerCallback = (credLogger, platform = coreUtil.isNode ? "Node" : "Browser") => (level, message, containsPii) => {
1435
+ if (containsPii) {
1436
+ return;
1437
+ }
1438
+ switch (level) {
1439
+ case msalCommon__namespace.LogLevel.Error:
1440
+ credLogger.info(`MSAL ${platform} V2 error: ${message}`);
1441
+ return;
1442
+ case msalCommon__namespace.LogLevel.Info:
1443
+ credLogger.info(`MSAL ${platform} V2 info message: ${message}`);
1444
+ return;
1445
+ case msalCommon__namespace.LogLevel.Verbose:
1446
+ credLogger.info(`MSAL ${platform} V2 verbose message: ${message}`);
1447
+ return;
1448
+ case msalCommon__namespace.LogLevel.Warning:
1449
+ credLogger.info(`MSAL ${platform} V2 warning: ${message}`);
1450
+ return;
1358
1451
  }
1359
- }
1360
-
1361
- // Copyright (c) Microsoft Corporation.
1362
- // 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
1452
  };
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);
1453
+ /**
1454
+ * @internal
1455
+ */
1456
+ function getMSALLogLevel(logLevel) {
1457
+ switch (logLevel) {
1458
+ case "error":
1459
+ return msalCommon__namespace.LogLevel.Error;
1460
+ case "info":
1461
+ return msalCommon__namespace.LogLevel.Info;
1462
+ case "verbose":
1463
+ return msalCommon__namespace.LogLevel.Verbose;
1464
+ case "warning":
1465
+ return msalCommon__namespace.LogLevel.Warning;
1466
+ default:
1467
+ // default msal logging level should be Info
1468
+ return msalCommon__namespace.LogLevel.Info;
1381
1469
  }
1382
1470
  }
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
1471
  /**
1390
- * Attempts to load a specific property from the VSCode configurations of the current OS.
1391
- * If it fails at any point, returns undefined.
1472
+ * Wraps core-util's randomUUID in order to allow for mocking in tests.
1473
+ * This prepares the library for the upcoming core-util update to ESM.
1474
+ *
1475
+ * @internal
1476
+ * @returns A string containing a random UUID
1392
1477
  */
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];
1402
- }
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");
1478
+ function randomUUID() {
1479
+ return coreUtil.randomUUID();
1480
+ }
1481
+ /**
1482
+ * Handles MSAL errors.
1483
+ */
1484
+ function handleMsalError(scopes, error, getTokenOptions) {
1485
+ if (error.name === "AuthError" ||
1486
+ error.name === "ClientAuthError" ||
1487
+ error.name === "BrowserAuthError") {
1488
+ const msalError = error;
1489
+ switch (msalError.errorCode) {
1490
+ case "endpoints_resolution_error":
1491
+ logger$i.info(formatError(scopes, error.message));
1492
+ return new CredentialUnavailableError(error.message);
1493
+ case "device_code_polling_cancelled":
1494
+ return new abortController.AbortError("The authentication has been aborted by the caller.");
1495
+ case "consent_required":
1496
+ case "interaction_required":
1497
+ case "login_required":
1498
+ logger$i.info(formatError(scopes, `Authentication returned errorCode ${msalError.errorCode}`));
1499
+ break;
1413
1500
  default:
1414
- return;
1501
+ logger$i.info(formatError(scopes, `Failed to acquire token: ${error.message}`));
1502
+ break;
1415
1503
  }
1416
1504
  }
1417
- catch (e) {
1418
- logger$n.info(`Failed to load the Visual Studio Code configuration file. Error: ${e.message}`);
1419
- return;
1505
+ if (error.name === "ClientConfigurationError" ||
1506
+ error.name === "BrowserConfigurationAuthError" ||
1507
+ error.name === "AbortError") {
1508
+ return error;
1509
+ }
1510
+ if (error.name === "NativeAuthError") {
1511
+ logger$i.info(formatError(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`));
1512
+ return error;
1420
1513
  }
1514
+ return new AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message });
1515
+ }
1516
+ // transformations.ts
1517
+ function publicToMsal(account) {
1518
+ const [environment] = account.authority.match(/([a-z]*\.[a-z]*\.[a-z]*)/) || [""];
1519
+ return Object.assign(Object.assign({}, account), { localAccountId: account.homeAccountId, environment });
1520
+ }
1521
+ function msalToPublic(clientId, account) {
1522
+ const record = {
1523
+ authority: getAuthority(account.tenantId, account.environment),
1524
+ homeAccountId: account.homeAccountId,
1525
+ tenantId: account.tenantId || DefaultTenantId,
1526
+ username: account.username,
1527
+ clientId,
1528
+ version: LatestAuthenticationRecordVersion,
1529
+ };
1530
+ return record;
1421
1531
  }
1422
1532
  /**
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.
1533
+ * Serializes an `AuthenticationRecord` into a string.
1426
1534
  *
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}.
1535
+ * The output of a serialized authentication record will contain the following properties:
1536
+ *
1537
+ * - "authority"
1538
+ * - "homeAccountId"
1539
+ * - "clientId"
1540
+ * - "tenantId"
1541
+ * - "username"
1542
+ * - "version"
1543
+ *
1544
+ * To later convert this string to a serialized `AuthenticationRecord`, please use the exported function `deserializeAuthenticationRecord()`.
1431
1545
  */
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);
1546
+ function serializeAuthenticationRecord(record) {
1547
+ return JSON.stringify(record);
1548
+ }
1549
+ /**
1550
+ * Deserializes a previously serialized authentication record from a string into an object.
1551
+ *
1552
+ * The input string must contain the following properties:
1553
+ *
1554
+ * - "authority"
1555
+ * - "homeAccountId"
1556
+ * - "clientId"
1557
+ * - "tenantId"
1558
+ * - "username"
1559
+ * - "version"
1560
+ *
1561
+ * If the version we receive is unsupported, an error will be thrown.
1562
+ *
1563
+ * At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
1564
+ *
1565
+ * @param serializedRecord - Authentication record previously serialized into string.
1566
+ * @returns AuthenticationRecord.
1567
+ */
1568
+ function deserializeAuthenticationRecord(serializedRecord) {
1569
+ const parsed = JSON.parse(serializedRecord);
1570
+ if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) {
1571
+ throw Error("Unsupported AuthenticationRecord version");
1459
1572
  }
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;
1468
- }
1469
- checkUnsupportedTenant(this.tenantId);
1573
+ return parsed;
1574
+ }
1575
+
1576
+ // Copyright (c) Microsoft Corporation.
1577
+ // Licensed under the MIT license.
1578
+ const msiName$1 = "ManagedIdentityCredential - IMDS";
1579
+ const logger$h = credentialLogger(msiName$1);
1580
+ /**
1581
+ * Generates the options used on the request for an access token.
1582
+ */
1583
+ function prepareRequestOptions(scopes, clientId, resourceId, options) {
1584
+ var _a;
1585
+ const resource = mapScopesToResource(scopes);
1586
+ if (!resource) {
1587
+ throw new Error(`${msiName$1}: Multiple scopes are not supported.`);
1470
1588
  }
1471
- /**
1472
- * Runs preparations for any further getToken, but only once.
1473
- */
1474
- prepareOnce() {
1475
- if (!this.preparePromise) {
1476
- this.preparePromise = this.prepare();
1589
+ const { skipQuery, skipMetadataHeader } = options || {};
1590
+ let query = "";
1591
+ // Pod Identity will try to process this request even if the Metadata header is missing.
1592
+ // We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
1593
+ if (!skipQuery) {
1594
+ const queryParameters = {
1595
+ resource,
1596
+ "api-version": imdsApiVersion,
1597
+ };
1598
+ if (clientId) {
1599
+ queryParameters.client_id = clientId;
1477
1600
  }
1478
- return this.preparePromise;
1601
+ if (resourceId) {
1602
+ queryParameters.msi_res_id = resourceId;
1603
+ }
1604
+ const params = new URLSearchParams(queryParameters);
1605
+ query = `?${params.toString()}`;
1479
1606
  }
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(" "));
1607
+ const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
1608
+ const rawHeaders = {
1609
+ Accept: "application/json",
1610
+ Metadata: "true",
1611
+ };
1612
+ // Remove the Metadata header to invoke a request error from some IMDS endpoints.
1613
+ if (skipMetadataHeader) {
1614
+ delete rawHeaders.Metadata;
1615
+ }
1616
+ return {
1617
+ // In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
1618
+ url: `${url}${query}`,
1619
+ method: "GET",
1620
+ headers: coreRestPipeline.createHttpHeaders(rawHeaders),
1621
+ };
1622
+ }
1623
+ /**
1624
+ * Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
1625
+ */
1626
+ const imdsMsi = {
1627
+ name: "imdsMsi",
1628
+ async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
1629
+ const resource = mapScopesToResource(scopes);
1630
+ if (!resource) {
1631
+ logger$h.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
1632
+ return false;
1500
1633
  }
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;
1634
+ // if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
1635
+ if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1636
+ return true;
1507
1637
  }
1508
- if (scopeString.indexOf("offline_access") < 0) {
1509
- scopeString += " offline_access";
1638
+ if (!identityClient) {
1639
+ throw new Error("Missing IdentityClient");
1510
1640
  }
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;
1641
+ const requestOptions = prepareRequestOptions(resource, clientId, resourceId, {
1642
+ skipMetadataHeader: true,
1643
+ skipQuery: true,
1644
+ });
1645
+ return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
1646
+ var _a, _b;
1647
+ requestOptions.tracingOptions = options.tracingOptions;
1648
+ // Create a request with a timeout since we expect that
1649
+ // not having a "Metadata" header should cause an error to be
1650
+ // returned quickly from the endpoint, proving its availability.
1651
+ const request = coreRestPipeline.createPipelineRequest(requestOptions);
1652
+ // Default to 1000 if the default of 0 is used.
1653
+ // Negative values can still be used to disable the timeout.
1654
+ request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
1655
+ // This MSI uses the imdsEndpoint to get the token, which only uses http://
1656
+ request.allowInsecureConnection = true;
1657
+ let response;
1658
+ try {
1659
+ logger$h.info(`${msiName$1}: Pinging the Azure IMDS endpoint`);
1660
+ response = await identityClient.sendRequest(request);
1527
1661
  }
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;
1662
+ catch (err) {
1663
+ // If the request failed, or Node.js was unable to establish a connection,
1664
+ // or the host was down, we'll assume the IMDS endpoint isn't available.
1665
+ if (coreUtil.isError(err)) {
1666
+ logger$h.verbose(`${msiName$1}: Caught error ${err.name}: ${err.message}`);
1667
+ }
1668
+ // 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" or "A socket operation was attempted to an unreachable host"
1669
+ // rather than just timing out, as expected.
1670
+ logger$h.info(`${msiName$1}: The Azure IMDS endpoint is unavailable`);
1671
+ return false;
1672
+ }
1673
+ if (response.status === 403) {
1674
+ if ((_b = response.bodyAsText) === null || _b === void 0 ? void 0 : _b.includes("unreachable")) {
1675
+ logger$h.info(`${msiName$1}: The Azure IMDS endpoint is unavailable`);
1676
+ logger$h.info(`${msiName$1}: ${response.bodyAsText}`);
1677
+ return false;
1678
+ }
1532
1679
  }
1680
+ // If we received any response, the endpoint is available
1681
+ logger$h.info(`${msiName$1}: The Azure IMDS endpoint is available`);
1682
+ return true;
1683
+ });
1684
+ },
1685
+ async getToken(configuration, getTokenOptions = {}) {
1686
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1687
+ if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1688
+ logger$h.info(`${msiName$1}: Using the Azure IMDS endpoint coming from the environment variable AZURE_POD_IDENTITY_AUTHORITY_HOST=${process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST}.`);
1533
1689
  }
1534
1690
  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;
1691
+ logger$h.info(`${msiName$1}: Using the default Azure IMDS endpoint ${imdsHost}.`);
1538
1692
  }
1539
- }
1540
- }
1693
+ let nextDelayInMs = configuration.retryConfig.startDelayInMs;
1694
+ for (let retries = 0; retries < configuration.retryConfig.maxRetries; retries++) {
1695
+ try {
1696
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
1697
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1698
+ return (tokenResponse && tokenResponse.accessToken) || null;
1699
+ }
1700
+ catch (error) {
1701
+ if (error.statusCode === 404) {
1702
+ await coreUtil.delay(nextDelayInMs);
1703
+ nextDelayInMs *= configuration.retryConfig.intervalIncrement;
1704
+ continue;
1705
+ }
1706
+ throw error;
1707
+ }
1708
+ }
1709
+ throw new AuthenticationError(404, `${msiName$1}: Failed to retrieve IMDS token after ${configuration.retryConfig.maxRetries} retries.`);
1710
+ },
1711
+ };
1541
1712
 
1542
1713
  // Copyright (c) Microsoft Corporation.
1543
1714
  // Licensed under the MIT license.
1544
1715
  /**
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
- /**
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";
1566
- *
1567
- * import { useIdentityPlugin, DefaultAzureCredential } from "@azure/identity";
1568
- * useIdentityPlugin(cachePersistencePlugin);
1569
- *
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
- * ```
1578
- *
1579
- * @param plugin - the plugin to register
1716
+ * Helps specify a regional authority, or "AutoDiscoverRegion" to auto-detect the region.
1580
1717
  */
1581
- function useIdentityPlugin(plugin) {
1582
- plugin(pluginContext);
1583
- }
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);
1718
+ var RegionalAuthority;
1719
+ (function (RegionalAuthority) {
1720
+ /** Instructs MSAL to attempt to discover the region */
1721
+ RegionalAuthority["AutoDiscoverRegion"] = "AutoDiscoverRegion";
1722
+ /** Uses the {@link RegionalAuthority} for the Azure 'westus' region. */
1723
+ RegionalAuthority["USWest"] = "westus";
1724
+ /** Uses the {@link RegionalAuthority} for the Azure 'westus2' region. */
1725
+ RegionalAuthority["USWest2"] = "westus2";
1726
+ /** Uses the {@link RegionalAuthority} for the Azure 'centralus' region. */
1727
+ RegionalAuthority["USCentral"] = "centralus";
1728
+ /** Uses the {@link RegionalAuthority} for the Azure 'eastus' region. */
1729
+ RegionalAuthority["USEast"] = "eastus";
1730
+ /** Uses the {@link RegionalAuthority} for the Azure 'eastus2' region. */
1731
+ RegionalAuthority["USEast2"] = "eastus2";
1732
+ /** Uses the {@link RegionalAuthority} for the Azure 'northcentralus' region. */
1733
+ RegionalAuthority["USNorthCentral"] = "northcentralus";
1734
+ /** Uses the {@link RegionalAuthority} for the Azure 'southcentralus' region. */
1735
+ RegionalAuthority["USSouthCentral"] = "southcentralus";
1736
+ /** Uses the {@link RegionalAuthority} for the Azure 'westcentralus' region. */
1737
+ RegionalAuthority["USWestCentral"] = "westcentralus";
1738
+ /** Uses the {@link RegionalAuthority} for the Azure 'canadacentral' region. */
1739
+ RegionalAuthority["CanadaCentral"] = "canadacentral";
1740
+ /** Uses the {@link RegionalAuthority} for the Azure 'canadaeast' region. */
1741
+ RegionalAuthority["CanadaEast"] = "canadaeast";
1742
+ /** Uses the {@link RegionalAuthority} for the Azure 'brazilsouth' region. */
1743
+ RegionalAuthority["BrazilSouth"] = "brazilsouth";
1744
+ /** Uses the {@link RegionalAuthority} for the Azure 'northeurope' region. */
1745
+ RegionalAuthority["EuropeNorth"] = "northeurope";
1746
+ /** Uses the {@link RegionalAuthority} for the Azure 'westeurope' region. */
1747
+ RegionalAuthority["EuropeWest"] = "westeurope";
1748
+ /** Uses the {@link RegionalAuthority} for the Azure 'uksouth' region. */
1749
+ RegionalAuthority["UKSouth"] = "uksouth";
1750
+ /** Uses the {@link RegionalAuthority} for the Azure 'ukwest' region. */
1751
+ RegionalAuthority["UKWest"] = "ukwest";
1752
+ /** Uses the {@link RegionalAuthority} for the Azure 'francecentral' region. */
1753
+ RegionalAuthority["FranceCentral"] = "francecentral";
1754
+ /** Uses the {@link RegionalAuthority} for the Azure 'francesouth' region. */
1755
+ RegionalAuthority["FranceSouth"] = "francesouth";
1756
+ /** Uses the {@link RegionalAuthority} for the Azure 'switzerlandnorth' region. */
1757
+ RegionalAuthority["SwitzerlandNorth"] = "switzerlandnorth";
1758
+ /** Uses the {@link RegionalAuthority} for the Azure 'switzerlandwest' region. */
1759
+ RegionalAuthority["SwitzerlandWest"] = "switzerlandwest";
1760
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanynorth' region. */
1761
+ RegionalAuthority["GermanyNorth"] = "germanynorth";
1762
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanywestcentral' region. */
1763
+ RegionalAuthority["GermanyWestCentral"] = "germanywestcentral";
1764
+ /** Uses the {@link RegionalAuthority} for the Azure 'norwaywest' region. */
1765
+ RegionalAuthority["NorwayWest"] = "norwaywest";
1766
+ /** Uses the {@link RegionalAuthority} for the Azure 'norwayeast' region. */
1767
+ RegionalAuthority["NorwayEast"] = "norwayeast";
1768
+ /** Uses the {@link RegionalAuthority} for the Azure 'eastasia' region. */
1769
+ RegionalAuthority["AsiaEast"] = "eastasia";
1770
+ /** Uses the {@link RegionalAuthority} for the Azure 'southeastasia' region. */
1771
+ RegionalAuthority["AsiaSouthEast"] = "southeastasia";
1772
+ /** Uses the {@link RegionalAuthority} for the Azure 'japaneast' region. */
1773
+ RegionalAuthority["JapanEast"] = "japaneast";
1774
+ /** Uses the {@link RegionalAuthority} for the Azure 'japanwest' region. */
1775
+ RegionalAuthority["JapanWest"] = "japanwest";
1776
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiaeast' region. */
1777
+ RegionalAuthority["AustraliaEast"] = "australiaeast";
1778
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiasoutheast' region. */
1779
+ RegionalAuthority["AustraliaSouthEast"] = "australiasoutheast";
1780
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiacentral' region. */
1781
+ RegionalAuthority["AustraliaCentral"] = "australiacentral";
1782
+ /** Uses the {@link RegionalAuthority} for the Azure 'australiacentral2' region. */
1783
+ RegionalAuthority["AustraliaCentral2"] = "australiacentral2";
1784
+ /** Uses the {@link RegionalAuthority} for the Azure 'centralindia' region. */
1785
+ RegionalAuthority["IndiaCentral"] = "centralindia";
1786
+ /** Uses the {@link RegionalAuthority} for the Azure 'southindia' region. */
1787
+ RegionalAuthority["IndiaSouth"] = "southindia";
1788
+ /** Uses the {@link RegionalAuthority} for the Azure 'westindia' region. */
1789
+ RegionalAuthority["IndiaWest"] = "westindia";
1790
+ /** Uses the {@link RegionalAuthority} for the Azure 'koreasouth' region. */
1791
+ RegionalAuthority["KoreaSouth"] = "koreasouth";
1792
+ /** Uses the {@link RegionalAuthority} for the Azure 'koreacentral' region. */
1793
+ RegionalAuthority["KoreaCentral"] = "koreacentral";
1794
+ /** Uses the {@link RegionalAuthority} for the Azure 'uaecentral' region. */
1795
+ RegionalAuthority["UAECentral"] = "uaecentral";
1796
+ /** Uses the {@link RegionalAuthority} for the Azure 'uaenorth' region. */
1797
+ RegionalAuthority["UAENorth"] = "uaenorth";
1798
+ /** Uses the {@link RegionalAuthority} for the Azure 'southafricanorth' region. */
1799
+ RegionalAuthority["SouthAfricaNorth"] = "southafricanorth";
1800
+ /** Uses the {@link RegionalAuthority} for the Azure 'southafricawest' region. */
1801
+ RegionalAuthority["SouthAfricaWest"] = "southafricawest";
1802
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinanorth' region. */
1803
+ RegionalAuthority["ChinaNorth"] = "chinanorth";
1804
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinaeast' region. */
1805
+ RegionalAuthority["ChinaEast"] = "chinaeast";
1806
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinanorth2' region. */
1807
+ RegionalAuthority["ChinaNorth2"] = "chinanorth2";
1808
+ /** Uses the {@link RegionalAuthority} for the Azure 'chinaeast2' region. */
1809
+ RegionalAuthority["ChinaEast2"] = "chinaeast2";
1810
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanycentral' region. */
1811
+ RegionalAuthority["GermanyCentral"] = "germanycentral";
1812
+ /** Uses the {@link RegionalAuthority} for the Azure 'germanynortheast' region. */
1813
+ RegionalAuthority["GermanyNorthEast"] = "germanynortheast";
1814
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgovvirginia' region. */
1815
+ RegionalAuthority["GovernmentUSVirginia"] = "usgovvirginia";
1816
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgoviowa' region. */
1817
+ RegionalAuthority["GovernmentUSIowa"] = "usgoviowa";
1818
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgovarizona' region. */
1819
+ RegionalAuthority["GovernmentUSArizona"] = "usgovarizona";
1820
+ /** Uses the {@link RegionalAuthority} for the Azure 'usgovtexas' region. */
1821
+ RegionalAuthority["GovernmentUSTexas"] = "usgovtexas";
1822
+ /** Uses the {@link RegionalAuthority} for the Azure 'usdodeast' region. */
1823
+ RegionalAuthority["GovernmentUSDodEast"] = "usdodeast";
1824
+ /** Uses the {@link RegionalAuthority} for the Azure 'usdodcentral' region. */
1825
+ RegionalAuthority["GovernmentUSDodCentral"] = "usdodcentral";
1826
+ })(RegionalAuthority || (RegionalAuthority = {}));
1589
1827
  /**
1590
- * Generates the options used on the request for an access token.
1828
+ * Calculates the correct regional authority based on the supplied value
1829
+ * and the AZURE_REGIONAL_AUTHORITY_NAME environment variable.
1830
+ *
1831
+ * Values will be returned verbatim, except for {@link RegionalAuthority.AutoDiscoverRegion}
1832
+ * which is mapped to a value MSAL can understand.
1833
+ *
1834
+ * @internal
1591
1835
  */
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`);
1836
+ function calculateRegionalAuthority(regionalAuthority) {
1837
+ var _a, _b;
1838
+ let azureRegion = regionalAuthority;
1839
+ if (azureRegion === undefined &&
1840
+ ((_b = (_a = globalThis.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.AZURE_REGIONAL_AUTHORITY_NAME) !== undefined) {
1841
+ azureRegion = process.env.AZURE_REGIONAL_AUTHORITY_NAME;
1608
1842
  }
1609
- if (!process.env.MSI_SECRET) {
1610
- throw new Error(`${msiName$6}: Missing environment variable: MSI_SECRET`);
1843
+ if (azureRegion === RegionalAuthority.AutoDiscoverRegion) {
1844
+ return "AUTO_DISCOVER";
1611
1845
  }
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
- };
1846
+ return azureRegion;
1620
1847
  }
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
1848
 
1653
1849
  // Copyright (c) Microsoft Corporation.
1654
1850
  // 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
1851
  /**
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.
1852
+ * MSAL partial base client for Node.js.
1853
+ *
1854
+ * It completes the input configuration with some default values.
1855
+ * It also provides with utility protected methods that can be used from any of the clients,
1856
+ * which includes handlers for successful responses and errors.
1857
+ *
1858
+ * @internal
1693
1859
  */
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;
1860
+ class MsalNode {
1861
+ constructor(options) {
1862
+ var _a, _b, _c, _d, _e, _f;
1863
+ this.app = {};
1864
+ this.caeApp = {};
1865
+ this.requiresConfidential = false;
1866
+ this.logger = options.logger;
1867
+ this.msalConfig = this.defaultNodeMsalConfig(options);
1868
+ this.tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
1869
+ this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
1870
+ this.clientId = this.msalConfig.auth.clientId;
1871
+ if (options === null || options === void 0 ? void 0 : options.getAssertion) {
1872
+ this.getAssertion = options.getAssertion;
1701
1873
  }
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.`);
1874
+ this.enableBroker = (_b = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _b === void 0 ? void 0 : _b.enabled;
1875
+ this.enableMsaPassthrough = (_c = options === null || options === void 0 ? void 0 : options.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough;
1876
+ this.parentWindowHandle = (_d = options.brokerOptions) === null || _d === void 0 ? void 0 : _d.parentWindowHandle;
1877
+ // If persistence has been configured
1878
+ if (persistenceProvider !== undefined && ((_e = options.tokenCachePersistenceOptions) === null || _e === void 0 ? void 0 : _e.enabled)) {
1879
+ const cacheBaseName = options.tokenCachePersistenceOptions.name || DEFAULT_TOKEN_CACHE_NAME;
1880
+ const nonCaeOptions = Object.assign({ name: `${cacheBaseName}.${CACHE_NON_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
1881
+ const caeOptions = Object.assign({ name: `${cacheBaseName}.${CACHE_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions);
1882
+ this.createCachePlugin = () => persistenceProvider(nonCaeOptions);
1883
+ this.createCachePluginCae = () => persistenceProvider(caeOptions);
1705
1884
  }
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.`);
1885
+ else if ((_f = options.tokenCachePersistenceOptions) === null || _f === void 0 ? void 0 : _f.enabled) {
1886
+ throw new Error([
1887
+ "Persistent token caching was requested, but no persistence provider was configured.",
1888
+ "You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)",
1889
+ "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
1890
+ "`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`.",
1891
+ ].join(" "));
1712
1892
  }
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.`);
1893
+ // If broker has not been configured
1894
+ if (!hasNativeBroker() && this.enableBroker) {
1895
+ throw new Error([
1896
+ "Broker for WAM was requested to be enabled, but no native broker was configured.",
1897
+ "You must install the identity-broker plugin package (`npm install --save @azure/identity-broker`)",
1898
+ "and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
1899
+ "`useIdentityPlugin(createNativeBrokerPlugin())` before using `enableBroker`.",
1900
+ ].join(" "));
1715
1901
  }
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
- };
1724
-
1725
- // Copyright (c) Microsoft Corporation.
1726
- // Licensed under the MIT license.
1727
- const msiName$4 = "ManagedIdentityCredential - IMDS";
1728
- const logger$k = credentialLogger(msiName$4);
1729
- /**
1730
- * Generates the options used on the request for an access token.
1731
- */
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.`);
1902
+ this.azureRegion = calculateRegionalAuthority(options.regionalAuthority);
1737
1903
  }
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,
1904
+ /**
1905
+ * Generates a MSAL configuration that generally works for Node.js
1906
+ */
1907
+ defaultNodeMsalConfig(options) {
1908
+ var _a;
1909
+ const clientId = options.clientId || DeveloperSignOnClientId;
1910
+ const tenantId = resolveTenantId(options.logger, options.tenantId, options.clientId);
1911
+ this.authorityHost = options.authorityHost || process.env.AZURE_AUTHORITY_HOST;
1912
+ const authority = getAuthority(tenantId, this.authorityHost);
1913
+ this.identityClient = new IdentityClient(Object.assign(Object.assign({}, options.tokenCredentialOptions), { authorityHost: authority, loggingOptions: options.loggingOptions }));
1914
+ const clientCapabilities = [];
1915
+ return {
1916
+ auth: {
1917
+ clientId,
1918
+ authority,
1919
+ knownAuthorities: getKnownAuthorities(tenantId, authority, options.disableInstanceDiscovery),
1920
+ clientCapabilities,
1921
+ },
1922
+ // Cache is defined in this.prepare();
1923
+ system: {
1924
+ networkClient: this.identityClient,
1925
+ loggerOptions: {
1926
+ loggerCallback: defaultLoggerCallback(options.logger),
1927
+ logLevel: getMSALLogLevel(logger$q.getLogLevel()),
1928
+ piiLoggingEnabled: (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.enableUnsafeSupportLogging,
1929
+ },
1930
+ },
1746
1931
  };
1747
- if (clientId) {
1748
- queryParameters.client_id = clientId;
1932
+ }
1933
+ getApp(appType, enableCae) {
1934
+ const app = enableCae ? this.caeApp : this.app;
1935
+ if (appType === "publicFirst") {
1936
+ return (app.public || app.confidential);
1749
1937
  }
1750
- if (resourceId) {
1751
- queryParameters.msi_res_id = resourceId;
1938
+ else if (appType === "confidentialFirst") {
1939
+ return (app.confidential || app.public);
1940
+ }
1941
+ else if (appType === "confidential") {
1942
+ return app.confidential;
1943
+ }
1944
+ else {
1945
+ return app.public;
1752
1946
  }
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
1947
  }
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;
1948
+ /**
1949
+ * Prepares the MSAL applications.
1950
+ */
1951
+ async init(options) {
1952
+ if (options === null || options === void 0 ? void 0 : options.abortSignal) {
1953
+ options.abortSignal.addEventListener("abort", () => {
1954
+ // This will abort any pending request in the IdentityClient,
1955
+ // based on the received or generated correlationId
1956
+ this.identityClient.abortRequests(options.correlationId);
1957
+ });
1958
+ }
1959
+ const app = (options === null || options === void 0 ? void 0 : options.enableCae) ? this.caeApp : this.app;
1960
+ if (options === null || options === void 0 ? void 0 : options.enableCae) {
1961
+ this.msalConfig.auth.clientCapabilities = ["cp1"];
1788
1962
  }
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;
1963
+ if (app.public || app.confidential) {
1964
+ return;
1792
1965
  }
1793
- if (!identityClient) {
1794
- throw new Error("Missing IdentityClient");
1966
+ if ((options === null || options === void 0 ? void 0 : options.enableCae) && this.createCachePluginCae !== undefined) {
1967
+ this.msalConfig.cache = {
1968
+ cachePlugin: await this.createCachePluginCae(),
1969
+ };
1795
1970
  }
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;
1827
- }
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
- }
1971
+ if (this.createCachePlugin !== undefined) {
1972
+ this.msalConfig.cache = {
1973
+ cachePlugin: await this.createCachePlugin(),
1974
+ };
1975
+ }
1976
+ if (hasNativeBroker() && this.enableBroker) {
1977
+ this.msalConfig.broker = {
1978
+ nativeBrokerPlugin: nativeBrokerInfo.broker,
1979
+ };
1980
+ if (!this.parentWindowHandle) {
1981
+ // error should have been thrown from within the constructor of InteractiveBrowserCredential
1982
+ this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
1834
1983
  }
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}.`);
1984
+ }
1985
+ if (options === null || options === void 0 ? void 0 : options.enableCae) {
1986
+ this.caeApp.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
1844
1987
  }
1845
1988
  else {
1846
- logger$k.info(`${msiName$4}: Using the default Azure IMDS endpoint ${imdsHost}.`);
1989
+ this.app.public = new msalCommon__namespace.PublicClientApplication(this.msalConfig);
1847
1990
  }
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;
1991
+ if (this.getAssertion) {
1992
+ this.msalConfig.auth.clientAssertion = await this.getAssertion();
1993
+ }
1994
+ // The confidential client requires either a secret, assertion or certificate.
1995
+ if (this.msalConfig.auth.clientSecret ||
1996
+ this.msalConfig.auth.clientAssertion ||
1997
+ this.msalConfig.auth.clientCertificate) {
1998
+ if (options === null || options === void 0 ? void 0 : options.enableCae) {
1999
+ this.caeApp.confidential = new msalCommon__namespace.ConfidentialClientApplication(this.msalConfig);
1854
2000
  }
1855
- catch (error) {
1856
- if (error.statusCode === 404) {
1857
- await coreUtil.delay(nextDelayInMs);
1858
- nextDelayInMs *= imdsMsiRetryConfig.intervalIncrement;
1859
- continue;
1860
- }
1861
- throw error;
2001
+ else {
2002
+ this.app.confidential = new msalCommon__namespace.ConfidentialClientApplication(this.msalConfig);
2003
+ }
2004
+ }
2005
+ else {
2006
+ if (this.requiresConfidential) {
2007
+ throw new Error("Unable to generate the MSAL confidential client. Missing either the client's secret, certificate or assertion.");
1862
2008
  }
1863
2009
  }
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
2010
  }
1880
- const queryParameters = {
1881
- resource,
1882
- "api-version": azureArcAPIVersion,
1883
- };
1884
- if (clientId) {
1885
- queryParameters.client_id = clientId;
2011
+ /**
2012
+ * Allows the cancellation of a MSAL request.
2013
+ */
2014
+ withCancellation(promise, abortSignal, onCancel) {
2015
+ return new Promise((resolve, reject) => {
2016
+ promise
2017
+ .then((msalToken) => {
2018
+ return resolve(msalToken);
2019
+ })
2020
+ .catch(reject);
2021
+ if (abortSignal) {
2022
+ abortSignal.addEventListener("abort", () => {
2023
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
2024
+ });
2025
+ }
2026
+ });
1886
2027
  }
1887
- if (resourceId) {
1888
- queryParameters.msi_res_id = resourceId;
2028
+ /**
2029
+ * Returns the existing account, attempts to load the account from MSAL.
2030
+ */
2031
+ async getActiveAccount(enableCae = false) {
2032
+ if (this.account) {
2033
+ return this.account;
2034
+ }
2035
+ const cache = this.getApp("confidentialFirst", enableCae).getTokenCache();
2036
+ const accountsByTenant = await (cache === null || cache === void 0 ? void 0 : cache.getAllAccounts());
2037
+ if (!accountsByTenant) {
2038
+ return;
2039
+ }
2040
+ if (accountsByTenant.length === 1) {
2041
+ this.account = msalToPublic(this.clientId, accountsByTenant[0]);
2042
+ }
2043
+ else {
2044
+ this.logger
2045
+ .info(`More than one account was found authenticated for this Client ID and Tenant ID.
2046
+ However, no "authenticationRecord" has been provided for this credential,
2047
+ therefore we're unable to pick between these accounts.
2048
+ A new login attempt will be requested, to ensure the correct account is picked.
2049
+ 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.`);
2050
+ return;
2051
+ }
2052
+ return this.account;
1889
2053
  }
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`);
2054
+ /**
2055
+ * Attempts to retrieve a token from cache.
2056
+ */
2057
+ async getTokenSilent(scopes, options) {
2058
+ var _a, _b, _c;
2059
+ await this.getActiveAccount(options === null || options === void 0 ? void 0 : options.enableCae);
2060
+ if (!this.account) {
2061
+ throw new AuthenticationRequiredError({
2062
+ scopes,
2063
+ getTokenOptions: options,
2064
+ message: "Silent authentication failed. We couldn't retrieve an active account from the cache.",
2065
+ });
2066
+ }
2067
+ const silentRequest = {
2068
+ // To be able to re-use the account, the Token Cache must also have been provided.
2069
+ account: publicToMsal(this.account),
2070
+ correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
2071
+ scopes,
2072
+ authority: options === null || options === void 0 ? void 0 : options.authority,
2073
+ claims: options === null || options === void 0 ? void 0 : options.claims,
2074
+ };
2075
+ if (hasNativeBroker() && this.enableBroker) {
2076
+ if (!silentRequest.tokenQueryParameters) {
2077
+ silentRequest.tokenQueryParameters = {};
2078
+ }
2079
+ if (!this.parentWindowHandle) {
2080
+ // error should have been thrown from within the constructor of InteractiveBrowserCredential
2081
+ this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
2082
+ }
2083
+ if (this.enableMsaPassthrough) {
2084
+ silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
2085
+ }
2086
+ }
2087
+ try {
2088
+ this.logger.info("Attempting to acquire token silently");
2089
+ /**
2090
+ * The following code to retrieve all accounts is done as a workaround in an attempt to force the
2091
+ * refresh of the token cache with the token and the account passed in through the
2092
+ * `authenticationRecord` parameter. See issue - https://github.com/Azure/azure-sdk-for-js/issues/24349#issuecomment-1496715651
2093
+ * This workaround serves as a workaround for silent authentication not happening when authenticationRecord is passed.
2094
+ */
2095
+ await ((_a = this.getApp("publicFirst", options === null || options === void 0 ? void 0 : options.enableCae)) === null || _a === void 0 ? void 0 : _a.getTokenCache().getAllAccounts());
2096
+ 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));
2097
+ return this.handleResult(scopes, response || undefined);
2098
+ }
2099
+ catch (err) {
2100
+ throw handleMsalError(scopes, err, options);
2101
+ }
1893
2102
  }
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);
2103
+ /**
2104
+ * Wrapper around each MSAL flow get token operation: doGetToken.
2105
+ * If disableAutomaticAuthentication is sent through the constructor, it will prevent MSAL from requesting the user input.
2106
+ */
2107
+ async getToken(scopes, options = {}) {
2108
+ const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds) ||
2109
+ this.tenantId;
2110
+ options.authority = getAuthority(tenantId, this.authorityHost);
2111
+ options.correlationId = (options === null || options === void 0 ? void 0 : options.correlationId) || randomUUID();
2112
+ await this.init(options);
2113
+ try {
2114
+ // MSAL now caches tokens based on their claims,
2115
+ // so now one has to keep track fo claims in order to retrieve the newer tokens from acquireTokenSilent
2116
+ // This update happened on PR: https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/4533
2117
+ const optionsClaims = options.claims;
2118
+ if (optionsClaims) {
2119
+ this.cachedClaims = optionsClaims;
2120
+ }
2121
+ if (this.cachedClaims && !optionsClaims) {
2122
+ options.claims = this.cachedClaims;
2123
+ }
2124
+ // We don't return the promise since we want to catch errors right here.
2125
+ return await this.getTokenSilent(scopes, options);
1913
2126
  }
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}`;
2127
+ catch (err) {
2128
+ if (err.name !== "AuthenticationRequiredError") {
2129
+ throw err;
2130
+ }
2131
+ if (options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication) {
2132
+ throw new AuthenticationRequiredError({
2133
+ scopes,
2134
+ getTokenOptions: options,
2135
+ message: "Automatic authentication has been disabled. You may call the authentication() method.",
2136
+ });
2137
+ }
2138
+ this.logger.info(`Silent authentication failed, falling back to interactive method.`);
2139
+ return this.doGetToken(scopes, options);
1926
2140
  }
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
2141
  }
1933
- catch (e) {
1934
- throw Error(`Invalid www-authenticate header format: ${authHeader}`);
2142
+ /**
2143
+ * Handles the MSAL authentication result.
2144
+ * If the result has an account, we update the local account reference.
2145
+ * If the token received is invalid, an error will be thrown depending on what's missing.
2146
+ */
2147
+ handleResult(scopes, result, getTokenOptions) {
2148
+ if (result === null || result === void 0 ? void 0 : result.account) {
2149
+ this.account = msalToPublic(this.clientId, result.account);
2150
+ }
2151
+ ensureValidMsalToken(scopes, result, getTokenOptions);
2152
+ this.logger.getToken.info(formatSuccess(scopes));
2153
+ return {
2154
+ token: result.accessToken,
2155
+ expiresOnTimestamp: result.expiresOn.getTime(),
2156
+ };
1935
2157
  }
1936
2158
  }
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;
1947
- }
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`);
1951
- }
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.`);
1959
- }
1960
- if (resourceId) {
1961
- logger$j.warning(`${msiName$3}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
1962
- }
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.`);
1968
- }
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
- };
1978
2159
 
1979
2160
  // Copyright (c) Microsoft Corporation.
1980
2161
  // Licensed under the MIT license.
@@ -2018,7 +2199,7 @@ class MsalClientAssertion extends MsalNode {
2018
2199
 
2019
2200
  // Copyright (c) Microsoft Corporation.
2020
2201
  // Licensed under the MIT license.
2021
- const logger$i = credentialLogger("ClientAssertionCredential");
2202
+ const logger$g = credentialLogger("ClientAssertionCredential");
2022
2203
  /**
2023
2204
  * Authenticates a service principal with a JWT assertion.
2024
2205
  */
@@ -2041,7 +2222,7 @@ class ClientAssertionCredential {
2041
2222
  this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
2042
2223
  this.clientId = clientId;
2043
2224
  this.options = options;
2044
- this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$i, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
2225
+ this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$g, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
2045
2226
  }
2046
2227
  /**
2047
2228
  * Authenticates with Microsoft Entra ID and returns an access token if successful.
@@ -2053,7 +2234,7 @@ class ClientAssertionCredential {
2053
2234
  */
2054
2235
  async getToken(scopes, options = {}) {
2055
2236
  return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
2056
- newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$i);
2237
+ newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$g);
2057
2238
  const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
2058
2239
  return this.msalFlow.getToken(arrayScopes, newOptions);
2059
2240
  });
@@ -2075,7 +2256,7 @@ const SupportedWorkloadEnvironmentVariables = [
2075
2256
  "AZURE_CLIENT_ID",
2076
2257
  "AZURE_FEDERATED_TOKEN_FILE",
2077
2258
  ];
2078
- const logger$h = credentialLogger(credentialName$3);
2259
+ const logger$f = credentialLogger(credentialName$3);
2079
2260
  /**
2080
2261
  * Workload Identity authentication is a feature in Azure that allows applications running on virtual machines (VMs)
2081
2262
  * to access other Azure resources without the need for a service principal or managed identity. With Workload Identity
@@ -2101,17 +2282,17 @@ class WorkloadIdentityCredential {
2101
2282
  this.cacheDate = undefined;
2102
2283
  // Logging environment variables for error details
2103
2284
  const assignedEnv = processEnvVars(SupportedWorkloadEnvironmentVariables).assigned.join(", ");
2104
- logger$h.info(`Found the following environment variables: ${assignedEnv}`);
2285
+ logger$f.info(`Found the following environment variables: ${assignedEnv}`);
2105
2286
  const workloadIdentityCredentialOptions = options !== null && options !== void 0 ? options : {};
2106
2287
  const tenantId = workloadIdentityCredentialOptions.tenantId || process.env.AZURE_TENANT_ID;
2107
2288
  const clientId = workloadIdentityCredentialOptions.clientId || process.env.AZURE_CLIENT_ID;
2108
2289
  this.federatedTokenFilePath =
2109
2290
  workloadIdentityCredentialOptions.tokenFilePath || process.env.AZURE_FEDERATED_TOKEN_FILE;
2110
2291
  if (tenantId) {
2111
- checkTenantId(logger$h, tenantId);
2292
+ checkTenantId(logger$f, tenantId);
2112
2293
  }
2113
2294
  if (clientId && tenantId && this.federatedTokenFilePath) {
2114
- logger$h.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, clientId: ${workloadIdentityCredentialOptions.clientId} and federated token path: [REDACTED]`);
2295
+ logger$f.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, clientId: ${workloadIdentityCredentialOptions.clientId} and federated token path: [REDACTED]`);
2115
2296
  this.client = new ClientAssertionCredential(tenantId, clientId, this.readFileContents.bind(this), options);
2116
2297
  }
2117
2298
  }
@@ -2130,10 +2311,10 @@ class WorkloadIdentityCredential {
2130
2311
  "AZURE_TENANT_ID",
2131
2312
  "AZURE_CLIENT_ID",
2132
2313
  "AZURE_FEDERATED_TOKEN_FILE". See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot `;
2133
- logger$h.info(errorMessage);
2314
+ logger$f.info(errorMessage);
2134
2315
  throw new CredentialUnavailableError(errorMessage);
2135
2316
  }
2136
- logger$h.info("Invoking getToken() of Client Assertion Credential");
2317
+ logger$f.info("Invoking getToken() of Client Assertion Credential");
2137
2318
  return this.client.getToken(scopes, options);
2138
2319
  }
2139
2320
  async readFileContents() {
@@ -2161,8 +2342,8 @@ class WorkloadIdentityCredential {
2161
2342
 
2162
2343
  // Copyright (c) Microsoft Corporation.
2163
2344
  // Licensed under the MIT license.
2164
- const msiName$2 = "ManagedIdentityCredential - Token Exchange";
2165
- const logger$g = credentialLogger(msiName$2);
2345
+ const msiName = "ManagedIdentityCredential - Token Exchange";
2346
+ const logger$e = credentialLogger(msiName);
2166
2347
  /**
2167
2348
  * Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
2168
2349
  */
@@ -2175,7 +2356,7 @@ function tokenExchangeMsi() {
2175
2356
  env.AZURE_TENANT_ID &&
2176
2357
  process.env.AZURE_FEDERATED_TOKEN_FILE);
2177
2358
  if (!result) {
2178
- logger$g.info(`${msiName$2}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
2359
+ logger$e.info(`${msiName}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
2179
2360
  }
2180
2361
  return result;
2181
2362
  },
@@ -2189,164 +2370,6 @@ function tokenExchangeMsi() {
2189
2370
  };
2190
2371
  }
2191
2372
 
2192
- // Copyright (c) Microsoft Corporation.
2193
- // Licensed under the MIT license.
2194
- // This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
2195
- //
2196
- // FROM node:12
2197
- // RUN wget https://host.any/path/bash.sh
2198
- // CMD ["bash", "bash.sh"]
2199
- //
2200
- // Where the bash script contains:
2201
- //
2202
- // curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
2203
- //
2204
- const msiName$1 = "ManagedIdentityCredential - Fabric MSI";
2205
- const logger$f = credentialLogger(msiName$1);
2206
- /**
2207
- * Generates the options used on the request for an access token.
2208
- */
2209
- function prepareRequestOptions$1(scopes, clientId, resourceId) {
2210
- const resource = mapScopesToResource(scopes);
2211
- if (!resource) {
2212
- throw new Error(`${msiName$1}: Multiple scopes are not supported.`);
2213
- }
2214
- const queryParameters = {
2215
- resource,
2216
- "api-version": azureFabricVersion,
2217
- };
2218
- if (clientId) {
2219
- queryParameters.client_id = clientId;
2220
- }
2221
- if (resourceId) {
2222
- queryParameters.msi_res_id = resourceId;
2223
- }
2224
- const query = new URLSearchParams(queryParameters);
2225
- // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
2226
- if (!process.env.IDENTITY_ENDPOINT) {
2227
- throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
2228
- }
2229
- if (!process.env.IDENTITY_HEADER) {
2230
- throw new Error("Missing environment variable: IDENTITY_HEADER");
2231
- }
2232
- return {
2233
- url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
2234
- method: "GET",
2235
- headers: coreRestPipeline.createHttpHeaders({
2236
- Accept: "application/json",
2237
- secret: process.env.IDENTITY_HEADER,
2238
- }),
2239
- };
2240
- }
2241
- /**
2242
- * Defines how to determine whether the Azure Service Fabric MSI is available, and also how to retrieve a token from the Azure Service Fabric MSI.
2243
- */
2244
- const fabricMsi = {
2245
- name: "fabricMsi",
2246
- async isAvailable({ scopes }) {
2247
- const resource = mapScopesToResource(scopes);
2248
- if (!resource) {
2249
- logger$f.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
2250
- return false;
2251
- }
2252
- const env = process.env;
2253
- const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
2254
- if (!result) {
2255
- logger$f.info(`${msiName$1}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
2256
- }
2257
- return result;
2258
- },
2259
- async getToken(configuration, getTokenOptions = {}) {
2260
- const { scopes, identityClient, clientId, resourceId } = configuration;
2261
- if (resourceId) {
2262
- logger$f.warning(`${msiName$1}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
2263
- }
2264
- logger$f.info([
2265
- `${msiName$1}:`,
2266
- "Using the endpoint and the secret coming from the environment variables:",
2267
- `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
2268
- "IDENTITY_HEADER=[REDACTED] and",
2269
- "IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
2270
- ].join(" "));
2271
- const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
2272
- request.agent = new https.Agent({
2273
- // This is necessary because Service Fabric provides a self-signed certificate.
2274
- // The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
2275
- rejectUnauthorized: false,
2276
- });
2277
- const tokenResponse = await identityClient.sendTokenRequest(request);
2278
- return (tokenResponse && tokenResponse.accessToken) || null;
2279
- },
2280
- };
2281
-
2282
- // Copyright (c) Microsoft Corporation.
2283
- // Licensed under the MIT license.
2284
- const msiName = "ManagedIdentityCredential - AppServiceMSI 2019";
2285
- const logger$e = credentialLogger(msiName);
2286
- /**
2287
- * Generates the options used on the request for an access token.
2288
- */
2289
- function prepareRequestOptions(scopes, clientId, resourceId) {
2290
- const resource = mapScopesToResource(scopes);
2291
- if (!resource) {
2292
- throw new Error(`${msiName}: Multiple scopes are not supported.`);
2293
- }
2294
- const queryParameters = {
2295
- resource,
2296
- "api-version": "2019-08-01",
2297
- };
2298
- if (clientId) {
2299
- queryParameters.client_id = clientId;
2300
- }
2301
- if (resourceId) {
2302
- queryParameters.mi_res_id = resourceId;
2303
- }
2304
- const query = new URLSearchParams(queryParameters);
2305
- // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
2306
- if (!process.env.IDENTITY_ENDPOINT) {
2307
- throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
2308
- }
2309
- if (!process.env.IDENTITY_HEADER) {
2310
- throw new Error(`${msiName}: Missing environment variable: IDENTITY_HEADER`);
2311
- }
2312
- return {
2313
- url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
2314
- method: "GET",
2315
- headers: coreRestPipeline.createHttpHeaders({
2316
- Accept: "application/json",
2317
- "X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
2318
- }),
2319
- };
2320
- }
2321
- /**
2322
- * 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.
2323
- */
2324
- const appServiceMsi2019 = {
2325
- name: "appServiceMsi2019",
2326
- async isAvailable({ scopes }) {
2327
- const resource = mapScopesToResource(scopes);
2328
- if (!resource) {
2329
- logger$e.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
2330
- return false;
2331
- }
2332
- const env = process.env;
2333
- const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
2334
- if (!result) {
2335
- logger$e.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
2336
- }
2337
- return result;
2338
- },
2339
- async getToken(configuration, getTokenOptions = {}) {
2340
- const { identityClient, scopes, clientId, resourceId } = configuration;
2341
- logger$e.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
2342
- const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
2343
- // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
2344
- allowInsecureConnection: true }));
2345
- const tokenResponse = await identityClient.sendTokenRequest(request);
2346
- return (tokenResponse && tokenResponse.accessToken) || null;
2347
- },
2348
- };
2349
-
2350
2373
  // Copyright (c) Microsoft Corporation.
2351
2374
  // Licensed under the MIT license.
2352
2375
  const logger$d = credentialLogger("ManagedIdentityCredential");
@@ -2364,9 +2387,14 @@ class ManagedIdentityCredential {
2364
2387
  * @hidden
2365
2388
  */
2366
2389
  constructor(clientIdOrOptions, options) {
2367
- var _a;
2390
+ var _a, _b;
2368
2391
  this.isEndpointUnavailable = null;
2369
2392
  this.isAppTokenProviderInitialized = false;
2393
+ this.msiRetryConfig = {
2394
+ maxRetries: 5,
2395
+ startDelayInMs: 800,
2396
+ intervalIncrement: 2,
2397
+ };
2370
2398
  let _options;
2371
2399
  if (typeof clientIdOrOptions === "string") {
2372
2400
  this.clientId = clientIdOrOptions;
@@ -2381,6 +2409,9 @@ class ManagedIdentityCredential {
2381
2409
  if (this.clientId && this.resourceId) {
2382
2410
  throw new Error(`${ManagedIdentityCredential.name} - Client Id and Resource Id can't be provided at the same time.`);
2383
2411
  }
2412
+ if (((_a = _options === null || _options === void 0 ? void 0 : _options.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== undefined) {
2413
+ this.msiRetryConfig.maxRetries = _options.retryOptions.maxRetries;
2414
+ }
2384
2415
  this.identityClient = new IdentityClient(_options);
2385
2416
  this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
2386
2417
  maxRetries: 0,
@@ -2391,7 +2422,7 @@ class ManagedIdentityCredential {
2391
2422
  this.confidentialApp = new msalCommon.ConfidentialClientApplication({
2392
2423
  auth: {
2393
2424
  authority: "https://login.microsoftonline.com/managed_identity",
2394
- clientId: (_a = this.clientId) !== null && _a !== void 0 ? _a : DeveloperSignOnClientId,
2425
+ clientId: (_b = this.clientId) !== null && _b !== void 0 ? _b : DeveloperSignOnClientId,
2395
2426
  clientSecret: "dummy-secret",
2396
2427
  cloudDiscoveryMetadata: '{"tenant_discovery_endpoint":"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}',
2397
2428
  authorityMetadata: '{"token_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/common/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"kerberos_endpoint":"https://login.microsoftonline.com/common/kerberos","tenant_region_scope":null,"cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}',
@@ -2441,6 +2472,7 @@ class ManagedIdentityCredential {
2441
2472
  scopes,
2442
2473
  clientId: this.clientId,
2443
2474
  resourceId: this.resourceId,
2475
+ retryConfig: this.msiRetryConfig,
2444
2476
  }, updatedOptions);
2445
2477
  }
2446
2478
  catch (err) {
@@ -2547,10 +2579,10 @@ class ManagedIdentityCredential {
2547
2579
  if (err.statusCode === 400) {
2548
2580
  throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: The managed identity endpoint is indicating there's no available identity. Message: ${err.message}`);
2549
2581
  }
2550
- // 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"
2582
+ // 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" or "A socket operation was attempted to an unreachable host"
2551
2583
  // rather than just timing out, as expected.
2552
2584
  if (err.statusCode === 403 || err.code === 403) {
2553
- if (err.message.includes("A socket operation was attempted to an unreachable network")) {
2585
+ if (err.message.includes("unreachable")) {
2554
2586
  const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
2555
2587
  logger$d.getToken.info(formatError(scopes, error));
2556
2588
  throw error;
@@ -2587,7 +2619,6 @@ class ManagedIdentityCredential {
2587
2619
  }
2588
2620
  /**
2589
2621
  * Ensures the validity of the MSAL token
2590
- * @internal
2591
2622
  */
2592
2623
  ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
2593
2624
  const error = (message) => {
@@ -2891,7 +2922,7 @@ const logger$b = credentialLogger("AzureDeveloperCliCredential");
2891
2922
  * Azure Developer CLI is a command-line interface tool that allows developers to create, manage, and deploy
2892
2923
  * resources in Azure. It's built on top of the Azure CLI and provides additional functionality specific
2893
2924
  * to Azure developers. It allows users to authenticate as a user and/or a service principal against
2894
- * <a href="https://learn.microsoft.com/azure/active-directory/fundamentals/">Microsoft Entra ID</a>. The
2925
+ * <a href="https://learn.microsoft.com/entra/fundamentals/">Microsoft Entra ID</a>. The
2895
2926
  * AzureDeveloperCliCredential authenticates in a development environment and acquires a token on behalf of
2896
2927
  * the logged-in user or service principal in the Azure Developer CLI. It acts as the Azure Developer CLI logged in user or
2897
2928
  * service principal and executes an Azure CLI command underneath to authenticate the application against
@@ -3485,7 +3516,7 @@ const logger$7 = credentialLogger("ClientSecretCredential");
3485
3516
  * that was generated for an App Registration. More information on how
3486
3517
  * to configure a client secret can be found here:
3487
3518
  *
3488
- * https://learn.microsoft.com/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application
3519
+ * https://learn.microsoft.com/entra/identity-platform/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application
3489
3520
  *
3490
3521
  */
3491
3522
  class ClientSecretCredential {
@@ -3734,13 +3765,17 @@ const logger$4 = credentialLogger("DefaultAzureCredential");
3734
3765
  *
3735
3766
  * @internal
3736
3767
  */
3737
- function createDefaultManagedIdentityCredential(options) {
3738
- var _a, _b, _c;
3739
- const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
3740
- const workloadIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _b !== void 0 ? _b : managedIdentityClientId;
3768
+ function createDefaultManagedIdentityCredential(options = {}) {
3769
+ var _a, _b, _c, _d;
3770
+ (_a = options.retryOptions) !== null && _a !== void 0 ? _a : (options.retryOptions = {
3771
+ maxRetries: 5,
3772
+ retryDelayInMs: 800,
3773
+ });
3774
+ const managedIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _b !== void 0 ? _b : process.env.AZURE_CLIENT_ID;
3775
+ const workloadIdentityClientId = (_c = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _c !== void 0 ? _c : managedIdentityClientId;
3741
3776
  const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
3742
3777
  const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
3743
- const tenantId = (_c = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _c !== void 0 ? _c : process.env.AZURE_TENANT_ID;
3778
+ const tenantId = (_d = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _d !== void 0 ? _d : process.env.AZURE_TENANT_ID;
3744
3779
  if (managedResourceId) {
3745
3780
  const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
3746
3781
  return new ManagedIdentityCredential(managedIdentityResourceIdOptions);
@@ -3880,15 +3915,16 @@ const interactiveBrowserMockable = {
3880
3915
  */
3881
3916
  class MsalOpenBrowser extends MsalNode {
3882
3917
  constructor(options) {
3883
- var _a, _b;
3918
+ var _a, _b, _c, _d;
3884
3919
  super(options);
3885
3920
  this.loginHint = options.loginHint;
3886
3921
  this.errorTemplate = (_a = options.browserCustomizationOptions) === null || _a === void 0 ? void 0 : _a.errorMessage;
3887
3922
  this.successTemplate = (_b = options.browserCustomizationOptions) === null || _b === void 0 ? void 0 : _b.successMessage;
3888
3923
  this.logger = credentialLogger("Node.js MSAL Open Browser");
3924
+ this.useDefaultBrokerAccount =
3925
+ ((_c = options.brokerOptions) === null || _c === void 0 ? void 0 : _c.enabled) && ((_d = options.brokerOptions) === null || _d === void 0 ? void 0 : _d.useDefaultBrokerAccount);
3889
3926
  }
3890
- async doGetToken(scopes, options) {
3891
- var _a;
3927
+ async doGetToken(scopes, options = {}) {
3892
3928
  try {
3893
3929
  const interactiveRequest = {
3894
3930
  openBrowser: async (url) => {
@@ -3903,30 +3939,70 @@ class MsalOpenBrowser extends MsalNode {
3903
3939
  successTemplate: this.successTemplate,
3904
3940
  };
3905
3941
  if (hasNativeBroker() && this.enableBroker) {
3906
- this.logger.verbose("Authentication will resume through the broker");
3907
- if (this.parentWindowHandle) {
3908
- interactiveRequest.windowHandle = Buffer.from(this.parentWindowHandle);
3909
- }
3910
- else {
3911
- // error should have been thrown from within the constructor of InteractiveBrowserCredential
3912
- this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
3913
- }
3914
- if (this.enableMsaPassthrough) {
3915
- ((_a = interactiveRequest.tokenQueryParameters) !== null && _a !== void 0 ? _a : (interactiveRequest.tokenQueryParameters = {}))["msal_request_type"] =
3916
- "consumer_passthrough";
3917
- }
3942
+ return this.doGetBrokeredToken(scopes, interactiveRequest, {
3943
+ enableCae: options.enableCae,
3944
+ useDefaultBrokerAccount: this.useDefaultBrokerAccount,
3945
+ });
3918
3946
  }
3947
+ // If the broker is not enabled, we will fall back to interactive authentication
3919
3948
  if (hasNativeBroker() && !this.enableBroker) {
3920
3949
  this.logger.verbose("Authentication will resume normally without the broker, since it's not enabled");
3921
3950
  }
3951
+ const result = await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenInteractive(interactiveRequest);
3952
+ return this.handleResult(scopes, result || undefined);
3953
+ }
3954
+ catch (err) {
3955
+ throw handleMsalError(scopes, err, options);
3956
+ }
3957
+ }
3958
+ /**
3959
+ * A helper function that supports brokered authentication through the MSAL's public application.
3960
+ *
3961
+ * When options.useDefaultBrokerAccount is true, the method will attempt to authenticate using the default broker account.
3962
+ * If the default broker account is not available, the method will fall back to interactive authentication.
3963
+ */
3964
+ async doGetBrokeredToken(scopes, interactiveRequest, options) {
3965
+ var _a;
3966
+ this.logger.verbose("Authentication will resume through the broker");
3967
+ if (this.parentWindowHandle) {
3968
+ interactiveRequest.windowHandle = Buffer.from(this.parentWindowHandle);
3969
+ }
3970
+ else {
3971
+ // error should have been thrown from within the constructor of InteractiveBrowserCredential
3972
+ this.logger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
3973
+ }
3974
+ if (this.enableMsaPassthrough) {
3975
+ ((_a = interactiveRequest.tokenQueryParameters) !== null && _a !== void 0 ? _a : (interactiveRequest.tokenQueryParameters = {}))["msal_request_type"] =
3976
+ "consumer_passthrough";
3977
+ }
3978
+ if (options.useDefaultBrokerAccount) {
3979
+ interactiveRequest.prompt = "none";
3980
+ this.logger.verbose("Attempting broker authentication using the default broker account");
3981
+ }
3982
+ else {
3983
+ interactiveRequest.prompt = undefined;
3984
+ this.logger.verbose("Attempting broker authentication without the default broker account");
3985
+ }
3986
+ try {
3922
3987
  const result = await this.getApp("public", options === null || options === void 0 ? void 0 : options.enableCae).acquireTokenInteractive(interactiveRequest);
3923
3988
  if (result.fromNativeBroker) {
3924
3989
  this.logger.verbose(`This result is returned from native broker`);
3925
3990
  }
3926
3991
  return this.handleResult(scopes, result || undefined);
3927
3992
  }
3928
- catch (err) {
3929
- throw handleMsalError(scopes, err, options);
3993
+ catch (e) {
3994
+ this.logger.verbose(`Failed to authenticate through the broker: ${e.message}`);
3995
+ // If we tried to use the default broker account and failed, fall back to interactive authentication
3996
+ if (options.useDefaultBrokerAccount) {
3997
+ return this.doGetBrokeredToken(scopes, interactiveRequest, {
3998
+ enableCae: options.enableCae,
3999
+ useDefaultBrokerAccount: false,
4000
+ });
4001
+ }
4002
+ else {
4003
+ // If we're not using the default broker account, throw the error
4004
+ throw handleMsalError(scopes, e);
4005
+ }
3930
4006
  }
3931
4007
  }
3932
4008
  }
@@ -3942,17 +4018,17 @@ class InteractiveBrowserCredential {
3942
4018
  /**
3943
4019
  * Creates an instance of InteractiveBrowserCredential with the details needed.
3944
4020
  *
3945
- * This credential uses the [Authorization Code Flow](https://learn.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow).
4021
+ * This credential uses the [Authorization Code Flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow).
3946
4022
  * On Node.js, it will open a browser window while it listens for a redirect response from the authentication service.
3947
4023
  * On browsers, it authenticates via popups. The `loginStyle` optional parameter can be set to `redirect` to authenticate by redirecting the user to an Azure secure login page, which then will redirect the user back to the web application where the authentication started.
3948
4024
  *
3949
4025
  * For Node.js, if a `clientId` is provided, the Microsoft Entra application will need to be configured to have a "Mobile and desktop applications" redirect endpoint.
3950
- * Follow our guide on [setting up Redirect URIs for Desktop apps that calls to web APIs](https://learn.microsoft.com/azure/active-directory/develop/scenario-desktop-app-registration#redirect-uris).
4026
+ * Follow our guide on [setting up Redirect URIs for Desktop apps that calls to web APIs](https://learn.microsoft.com/entra/identity-platform/scenario-desktop-app-registration#redirect-uris).
3951
4027
  *
3952
4028
  * @param options - Options for configuring the client which makes the authentication requests.
3953
4029
  */
3954
4030
  constructor(options) {
3955
- var _a, _b, _c;
4031
+ var _a, _b, _c, _d;
3956
4032
  const redirectUri = typeof options.redirectUri === "function"
3957
4033
  ? options.redirectUri()
3958
4034
  : options.redirectUri || "http://localhost";
@@ -3969,6 +4045,7 @@ class InteractiveBrowserCredential {
3969
4045
  enabled: true,
3970
4046
  parentWindowHandle: ibcNodeOptions.brokerOptions.parentWindowHandle,
3971
4047
  legacyEnableMsaPassthrough: (_c = ibcNodeOptions.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough,
4048
+ useDefaultBrokerAccount: (_d = ibcNodeOptions.brokerOptions) === null || _d === void 0 ? void 0 : _d.useDefaultBrokerAccount,
3972
4049
  } }));
3973
4050
  }
3974
4051
  }
@@ -4183,7 +4260,7 @@ const logger$1 = credentialLogger("AuthorizationCodeCredential");
4183
4260
  * that was obtained through the authorization code flow, described in more detail
4184
4261
  * in the Microsoft Entra ID documentation:
4185
4262
  *
4186
- * https://learn.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow
4263
+ * https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow
4187
4264
  */
4188
4265
  class AuthorizationCodeCredential {
4189
4266
  /**
@@ -4290,7 +4367,7 @@ class MsalOnBehalfOf extends MsalNode {
4290
4367
  const credentialName = "OnBehalfOfCredential";
4291
4368
  const logger = credentialLogger(credentialName);
4292
4369
  /**
4293
- * Enables authentication to Microsoft Entra ID using the [On Behalf Of flow](https://learn.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
4370
+ * Enables authentication to Microsoft Entra ID using the [On Behalf Of flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow).
4294
4371
  */
4295
4372
  class OnBehalfOfCredential {
4296
4373
  constructor(options) {