@azure/identity 3.2.0-alpha.20230320.1 → 3.2.0-alpha.20230330.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 (35) hide show
  1. package/dist/index.js +105 -43
  2. package/dist/index.js.map +1 -1
  3. package/dist-esm/src/client/identityClient.js +3 -2
  4. package/dist-esm/src/client/identityClient.js.map +1 -1
  5. package/dist-esm/src/credentials/azureCliCredential.js +4 -3
  6. package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
  7. package/dist-esm/src/credentials/azureCliCredentialOptions.js.map +1 -1
  8. package/dist-esm/src/credentials/azureDeveloperCliCredential.js +8 -3
  9. package/dist-esm/src/credentials/azureDeveloperCliCredential.js.map +1 -1
  10. package/dist-esm/src/credentials/azureDeveloperCliCredentialOptions.js.map +1 -1
  11. package/dist-esm/src/credentials/azurePowerShellCredential.js +9 -5
  12. package/dist-esm/src/credentials/azurePowerShellCredential.js.map +1 -1
  13. package/dist-esm/src/credentials/azurePowerShellCredentialOptions.js.map +1 -1
  14. package/dist-esm/src/credentials/defaultAzureCredential.js +18 -3
  15. package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
  16. package/dist-esm/src/credentials/defaultAzureCredentialOptions.js.map +1 -1
  17. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +2 -1
  18. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
  19. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2019.js +2 -1
  20. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2019.js.map +1 -1
  21. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +2 -1
  22. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
  23. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +2 -1
  24. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
  25. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +2 -1
  26. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
  27. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +2 -1
  28. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
  29. package/dist-esm/src/credentials/managedIdentityCredential/index.js +32 -21
  30. package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
  31. package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -1
  32. package/dist-esm/src/credentials/managedIdentityCredential/utils.js +20 -1
  33. package/dist-esm/src/credentials/managedIdentityCredential/utils.js.map +1 -1
  34. package/package.json +1 -1
  35. package/types/identity.d.ts +17 -0
package/dist/index.js CHANGED
@@ -667,7 +667,7 @@ function mapScopesToResource(scopes) {
667
667
  * Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.
668
668
  * @param body - A parsed response body from the authentication endpoint.
669
669
  */
670
- function parseExpiresOn(body) {
670
+ function parseExpirationTimestamp(body) {
671
671
  if (typeof body.expires_on === "number") {
672
672
  return body.expires_on * 1000;
673
673
  }
@@ -686,6 +686,25 @@ function parseExpiresOn(body) {
686
686
  }
687
687
  throw new Error(`Failed to parse token expiration from body. expires_in="${body.expires_in}", expires_on="${body.expires_on}"`);
688
688
  }
689
+ /**
690
+ * Given a token response, return the timestamp for refreshing token as the number of milliseconds from the Unix epoch.
691
+ * @param body - A parsed response body from the authentication endpoint.
692
+ */
693
+ function parseRefreshTimestamp(body) {
694
+ if (typeof body.refresh_in === "number") {
695
+ return Date.now() + body.refresh_in * 1000;
696
+ }
697
+ else {
698
+ const durationInMilliseconds = parseExpirationTimestamp(body) - Date.now();
699
+ const durationInHours = Math.floor(durationInMilliseconds / 1000 / 60 / 60);
700
+ if (durationInHours >= 2) {
701
+ return Date.now() + durationInMilliseconds / 2;
702
+ }
703
+ else {
704
+ return Date.now() + durationInMilliseconds;
705
+ }
706
+ }
707
+ }
689
708
 
690
709
  // Copyright (c) Microsoft Corporation.
691
710
  const noCorrelationId = "noCorrelationId";
@@ -743,8 +762,9 @@ class IdentityClient extends coreClient.ServiceClient {
743
762
  const token = {
744
763
  accessToken: {
745
764
  token: parsedBody.access_token,
746
- expiresOnTimestamp: parseExpiresOn(parsedBody),
765
+ expiresOnTimestamp: parseExpirationTimestamp(parsedBody),
747
766
  },
767
+ refreshesIn: parseRefreshTimestamp(parsedBody),
748
768
  refreshToken: parsedBody.refresh_token,
749
769
  };
750
770
  logger$n.info(`IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`);
@@ -1548,7 +1568,8 @@ const appServiceMsi2017 = {
1548
1568
  // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1549
1569
  allowInsecureConnection: true }));
1550
1570
  const tokenResponse = await identityClient.sendTokenRequest(request);
1551
- return (tokenResponse && tokenResponse.accessToken) || null;
1571
+ return ((tokenResponse && Object.assign(Object.assign({}, tokenResponse.accessToken), { refreshesOn: tokenResponse.refreshesIn })) ||
1572
+ null);
1552
1573
  },
1553
1574
  };
1554
1575
 
@@ -1619,7 +1640,8 @@ const cloudShellMsi = {
1619
1640
  // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1620
1641
  allowInsecureConnection: true }));
1621
1642
  const tokenResponse = await identityClient.sendTokenRequest(request);
1622
- return (tokenResponse && tokenResponse.accessToken) || null;
1643
+ return ((tokenResponse && Object.assign(Object.assign({}, tokenResponse.accessToken), { refreshesOn: tokenResponse.refreshesIn })) ||
1644
+ null);
1623
1645
  },
1624
1646
  };
1625
1647
 
@@ -1740,7 +1762,8 @@ const imdsMsi = {
1740
1762
  try {
1741
1763
  const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
1742
1764
  const tokenResponse = await identityClient.sendTokenRequest(request);
1743
- return (tokenResponse && tokenResponse.accessToken) || null;
1765
+ return ((tokenResponse && Object.assign(Object.assign({}, tokenResponse.accessToken), { refreshesOn: tokenResponse.refreshesIn })) ||
1766
+ null);
1744
1767
  }
1745
1768
  catch (error) {
1746
1769
  if (error.statusCode === 404) {
@@ -1861,7 +1884,8 @@ const arcMsi = {
1861
1884
  // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1862
1885
  allowInsecureConnection: true }));
1863
1886
  const tokenResponse = await identityClient.sendTokenRequest(request);
1864
- return (tokenResponse && tokenResponse.accessToken) || null;
1887
+ return ((tokenResponse && Object.assign(Object.assign({}, tokenResponse.accessToken), { refreshesOn: tokenResponse.refreshesIn })) ||
1888
+ null);
1865
1889
  },
1866
1890
  };
1867
1891
 
@@ -2160,7 +2184,8 @@ const fabricMsi = {
2160
2184
  rejectUnauthorized: false,
2161
2185
  });
2162
2186
  const tokenResponse = await identityClient.sendTokenRequest(request);
2163
- return (tokenResponse && tokenResponse.accessToken) || null;
2187
+ return ((tokenResponse && Object.assign(Object.assign({}, tokenResponse.accessToken), { refreshesOn: tokenResponse.refreshesIn })) ||
2188
+ null);
2164
2189
  },
2165
2190
  };
2166
2191
 
@@ -2227,7 +2252,8 @@ const appServiceMsi2019 = {
2227
2252
  // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
2228
2253
  allowInsecureConnection: true }));
2229
2254
  const tokenResponse = await identityClient.sendTokenRequest(request);
2230
- return (tokenResponse && tokenResponse.accessToken) || null;
2255
+ return ((tokenResponse && Object.assign(Object.assign({}, tokenResponse.accessToken), { refreshesOn: tokenResponse.refreshesIn })) ||
2256
+ null);
2231
2257
  },
2232
2258
  };
2233
2259
 
@@ -2249,6 +2275,7 @@ class ManagedIdentityCredential {
2249
2275
  constructor(clientIdOrOptions, options) {
2250
2276
  var _a;
2251
2277
  this.isEndpointUnavailable = null;
2278
+ this.isAppTokenProviderInitialized = false;
2252
2279
  let _options;
2253
2280
  if (typeof clientIdOrOptions === "string") {
2254
2281
  this.clientId = clientIdOrOptions;
@@ -2357,27 +2384,37 @@ class ManagedIdentityCredential {
2357
2384
  scopes: Array.isArray(scopes) ? scopes : [scopes],
2358
2385
  claims: options === null || options === void 0 ? void 0 : options.claims,
2359
2386
  };
2360
- this.confidentialApp.SetAppTokenProvider(async (appTokenProviderParameters = appTokenParameters) => {
2361
- logger$c.info(`SetAppTokenProvider invoked with parameters- ${JSON.stringify(appTokenProviderParameters)}`);
2362
- const resultToken = await this.authenticateManagedIdentity(scopes, Object.assign(Object.assign({}, updatedOptions), appTokenProviderParameters));
2363
- if (resultToken) {
2364
- logger$c.info(`SetAppTokenProvider has saved the token in cache`);
2365
- const expiresInSeconds = (resultToken === null || resultToken === void 0 ? void 0 : resultToken.expiresOnTimestamp)
2366
- ? Math.floor((resultToken.expiresOnTimestamp - Date.now()) / 1000)
2367
- : 0;
2368
- return {
2369
- accessToken: resultToken === null || resultToken === void 0 ? void 0 : resultToken.token,
2370
- expiresInSeconds,
2371
- };
2372
- }
2373
- else {
2374
- logger$c.info(`SetAppTokenProvider token has "no_access_token_returned" as the saved token`);
2375
- return {
2376
- accessToken: "no_access_token_returned",
2377
- expiresInSeconds: 0,
2378
- };
2379
- }
2380
- });
2387
+ // Added a check to see if SetAppTokenProvider was already defined.
2388
+ // Don't redefine it if it's already defined, since it should be static method.
2389
+ if (!this.isAppTokenProviderInitialized) {
2390
+ this.confidentialApp.SetAppTokenProvider(async (appTokenProviderParameters = appTokenParameters) => {
2391
+ logger$c.info(`SetAppTokenProvider invoked with parameters- ${JSON.stringify(appTokenProviderParameters)}`);
2392
+ const resultToken = await this.authenticateManagedIdentity(scopes, Object.assign(Object.assign({}, updatedOptions), appTokenProviderParameters));
2393
+ if (resultToken) {
2394
+ logger$c.info(`SetAppTokenProvider has saved the token in cache`);
2395
+ const expiresInSeconds = (resultToken === null || resultToken === void 0 ? void 0 : resultToken.expiresOnTimestamp)
2396
+ ? Math.floor((resultToken.expiresOnTimestamp - Date.now()) / 1000)
2397
+ : 0;
2398
+ const refreshInSeconds = (resultToken === null || resultToken === void 0 ? void 0 : resultToken.refreshesOn)
2399
+ ? Math.floor((resultToken.refreshesOn - Date.now()) / 1000)
2400
+ : 0;
2401
+ return {
2402
+ accessToken: resultToken === null || resultToken === void 0 ? void 0 : resultToken.token,
2403
+ expiresInSeconds,
2404
+ refreshInSeconds,
2405
+ };
2406
+ }
2407
+ else {
2408
+ logger$c.info(`SetAppTokenProvider token has "no_access_token_returned" as the saved token`);
2409
+ return {
2410
+ accessToken: "no_access_token_returned",
2411
+ expiresInSeconds: 0,
2412
+ refreshInSeconds: 0,
2413
+ };
2414
+ }
2415
+ });
2416
+ this.isAppTokenProviderInitialized = true;
2417
+ }
2381
2418
  const authenticationResult = await this.confidentialApp.acquireTokenByClientCredential(Object.assign({}, appTokenParameters));
2382
2419
  result = this.handleResult(scopes, authenticationResult || undefined);
2383
2420
  }
@@ -2547,7 +2584,7 @@ const cliCredentialInternals = {
2547
2584
  * @param resource - The resource to use when getting the token
2548
2585
  * @internal
2549
2586
  */
2550
- async getAzureCliAccessToken(resource, tenantId) {
2587
+ async getAzureCliAccessToken(resource, tenantId, timeout) {
2551
2588
  let tenantSection = [];
2552
2589
  if (tenantId) {
2553
2590
  tenantSection = ["--tenant", tenantId];
@@ -2562,7 +2599,7 @@ const cliCredentialInternals = {
2562
2599
  "--resource",
2563
2600
  resource,
2564
2601
  ...tenantSection,
2565
- ], { cwd: cliCredentialInternals.getSafeWorkingDir(), shell: true }, (error, stdout, stderr) => {
2602
+ ], { cwd: cliCredentialInternals.getSafeWorkingDir(), shell: true, timeout }, (error, stdout, stderr) => {
2566
2603
  resolve({ stdout: stdout, stderr: stderr, error });
2567
2604
  });
2568
2605
  }
@@ -2591,6 +2628,7 @@ class AzureCliCredential {
2591
2628
  constructor(options) {
2592
2629
  this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
2593
2630
  this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
2631
+ this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
2594
2632
  }
2595
2633
  /**
2596
2634
  * Authenticates with Azure Active Directory and returns an access token if successful.
@@ -2609,7 +2647,7 @@ class AzureCliCredential {
2609
2647
  return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
2610
2648
  var _a, _b, _c, _d;
2611
2649
  try {
2612
- const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId);
2650
+ const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId, this.timeout);
2613
2651
  const specificScope = (_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("(.*)az login --scope(.*)");
2614
2652
  const isLoginError = ((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("(.*)az login(.*)")) && !specificScope;
2615
2653
  const isNotInstallError = ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.match("az:(.*)not found")) || ((_d = obj.stderr) === null || _d === void 0 ? void 0 : _d.startsWith("'az' is not recognized"));
@@ -2702,11 +2740,14 @@ function formatCommand(commandName) {
2702
2740
  * If anything fails, an error is thrown.
2703
2741
  * @internal
2704
2742
  */
2705
- async function runCommands(commands) {
2743
+ async function runCommands(commands, timeout) {
2706
2744
  const results = [];
2707
2745
  for (const command of commands) {
2708
2746
  const [file, ...parameters] = command;
2709
- const result = (await processUtils.execFile(file, parameters, { encoding: "utf8" }));
2747
+ const result = (await processUtils.execFile(file, parameters, {
2748
+ encoding: "utf8",
2749
+ timeout,
2750
+ }));
2710
2751
  results.push(result);
2711
2752
  }
2712
2753
  return results;
@@ -2761,16 +2802,17 @@ class AzurePowerShellCredential {
2761
2802
  constructor(options) {
2762
2803
  this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
2763
2804
  this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
2805
+ this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
2764
2806
  }
2765
2807
  /**
2766
2808
  * Gets the access token from Azure PowerShell
2767
2809
  * @param resource - The resource to use when getting the token
2768
2810
  */
2769
- async getAzurePowerShellAccessToken(resource, tenantId) {
2811
+ async getAzurePowerShellAccessToken(resource, tenantId, timeout) {
2770
2812
  // Clone the stack to avoid mutating it while iterating
2771
2813
  for (const powerShellCommand of [...commandStack]) {
2772
2814
  try {
2773
- await runCommands([[powerShellCommand, "/?"]]);
2815
+ await runCommands([[powerShellCommand, "/?"]], timeout);
2774
2816
  }
2775
2817
  catch (e) {
2776
2818
  // Remove this credential from the original stack so that we don't try it again.
@@ -2818,7 +2860,7 @@ class AzurePowerShellCredential {
2818
2860
  logger$a.getToken.info(`Using the scope ${scope}`);
2819
2861
  const resource = getScopeResource(scope);
2820
2862
  try {
2821
- const response = await this.getAzurePowerShellAccessToken(resource, tenantId);
2863
+ const response = await this.getAzurePowerShellAccessToken(resource, tenantId, this.timeout);
2822
2864
  logger$a.getToken.info(formatSuccess(scopes));
2823
2865
  return {
2824
2866
  token: response.Token,
@@ -3376,7 +3418,7 @@ const developerCliCredentialInternals = {
3376
3418
  * @param scopes - The scopes to use when getting the token
3377
3419
  * @internal
3378
3420
  */
3379
- async getAzdAccessToken(scopes, tenantId) {
3421
+ async getAzdAccessToken(scopes, tenantId, timeout) {
3380
3422
  let tenantSection = [];
3381
3423
  if (tenantId) {
3382
3424
  tenantSection = ["--tenant-id", tenantId];
@@ -3390,7 +3432,11 @@ const developerCliCredentialInternals = {
3390
3432
  "json",
3391
3433
  ...scopes.reduce((previous, current) => previous.concat("--scope", current), []),
3392
3434
  ...tenantSection,
3393
- ], { cwd: developerCliCredentialInternals.getSafeWorkingDir(), shell: true }, (error, stdout, stderr) => {
3435
+ ], {
3436
+ cwd: developerCliCredentialInternals.getSafeWorkingDir(),
3437
+ shell: true,
3438
+ timeout,
3439
+ }, (error, stdout, stderr) => {
3394
3440
  resolve({ stdout, stderr, error });
3395
3441
  });
3396
3442
  }
@@ -3419,6 +3465,7 @@ class AzureDeveloperCliCredential {
3419
3465
  constructor(options) {
3420
3466
  this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
3421
3467
  this.additionallyAllowedTenantIds = resolveAddionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
3468
+ this.timeout = options === null || options === void 0 ? void 0 : options.processTimeoutInMs;
3422
3469
  }
3423
3470
  /**
3424
3471
  * Authenticates with Azure Active Directory and returns an access token if successful.
@@ -3441,7 +3488,7 @@ class AzureDeveloperCliCredential {
3441
3488
  return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
3442
3489
  var _a, _b, _c;
3443
3490
  try {
3444
- const obj = await developerCliCredentialInternals.getAzdAccessToken(scopeList, tenantId);
3491
+ const obj = await developerCliCredentialInternals.getAzdAccessToken(scopeList, tenantId, this.timeout);
3445
3492
  const isNotLoggedInError = (_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("not logged in, run `azd login` to login");
3446
3493
  const isNotInstallError = ((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("azd:(.*)not found")) ||
3447
3494
  ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.startsWith("'azd' is not recognized"));
@@ -3516,13 +3563,28 @@ class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
3516
3563
  }
3517
3564
  }
3518
3565
  }
3566
+ class DefaultAzureDeveloperCliCredential extends AzureDeveloperCliCredential {
3567
+ constructor(options) {
3568
+ super(Object.assign({ processTimeoutInMs: options === null || options === void 0 ? void 0 : options.developerCredentialTimeOutInMs }, options));
3569
+ }
3570
+ }
3571
+ class DefaultAzureCliCredential extends AzureCliCredential {
3572
+ constructor(options) {
3573
+ super(Object.assign({ processTimeoutInMs: options === null || options === void 0 ? void 0 : options.developerCredentialTimeOutInMs }, options));
3574
+ }
3575
+ }
3576
+ class DefaultAzurePowershellCredential extends AzurePowerShellCredential {
3577
+ constructor(options) {
3578
+ super(Object.assign({ processTimeoutInMs: options === null || options === void 0 ? void 0 : options.developerCredentialTimeOutInMs }, options));
3579
+ }
3580
+ }
3519
3581
  const defaultCredentials = [
3520
3582
  EnvironmentCredential,
3521
3583
  WorkloadIdentityCredential,
3522
3584
  DefaultManagedIdentityCredential,
3523
- AzureDeveloperCliCredential,
3524
- AzureCliCredential,
3525
- AzurePowerShellCredential,
3585
+ DefaultAzureDeveloperCliCredential,
3586
+ DefaultAzureCliCredential,
3587
+ DefaultAzurePowershellCredential,
3526
3588
  ];
3527
3589
  /**
3528
3590
  * Provides a default {@link ChainedTokenCredential} configuration that should