@azure/storage-queue 12.15.0 → 12.16.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -327,8 +327,8 @@ function ipRangeToString(ipRange) {
327
327
 
328
328
  // Copyright (c) Microsoft Corporation.
329
329
  // Licensed under the MIT license.
330
- const SDK_VERSION = "12.15.0";
331
- const SERVICE_VERSION = "2023-08-03";
330
+ const SDK_VERSION = "12.16.0-beta.1";
331
+ const SERVICE_VERSION = "2023-11-03";
332
332
  /**
333
333
  * The OAuth scope to use with Azure Storage.
334
334
  */
@@ -444,7 +444,7 @@ const PathStylePorts = [
444
444
  * Changes may cause incorrect behavior and will be lost if the code is regenerated.
445
445
  */
446
446
  const packageName = "azure-storage-queue";
447
- const packageVersion = "12.15.0";
447
+ const packageVersion = "12.16.0-beta.1";
448
448
  class StorageClientContext extends coreHttp__namespace.ServiceClient {
449
449
  /**
450
450
  * Initializes a new instance of the StorageClientContext class.
@@ -470,7 +470,7 @@ class StorageClientContext extends coreHttp__namespace.ServiceClient {
470
470
  // Parameter assignments
471
471
  this.url = url;
472
472
  // Assigning values to Constant parameters
473
- this.version = options.version || "2023-08-03";
473
+ this.version = options.version || "2023-11-03";
474
474
  }
475
475
  }
476
476
 
@@ -1576,6 +1576,247 @@ function getCachedDefaultHttpClient() {
1576
1576
  return _defaultHttpClient;
1577
1577
  }
1578
1578
 
1579
+ // Copyright (c) Microsoft Corporation.
1580
+ /**
1581
+ * A set of constants used internally when processing requests.
1582
+ */
1583
+ const Constants = {
1584
+ DefaultScope: "/.default",
1585
+ /**
1586
+ * Defines constants for use with HTTP headers.
1587
+ */
1588
+ HeaderConstants: {
1589
+ /**
1590
+ * The Authorization header.
1591
+ */
1592
+ AUTHORIZATION: "authorization",
1593
+ },
1594
+ };
1595
+ // Default options for the cycler if none are provided
1596
+ const DEFAULT_CYCLER_OPTIONS = {
1597
+ forcedRefreshWindowInMs: 1000,
1598
+ retryIntervalInMs: 3000,
1599
+ refreshWindowInMs: 1000 * 60 * 2, // Start refreshing 2m before expiry
1600
+ };
1601
+ /**
1602
+ * Converts an an unreliable access token getter (which may resolve with null)
1603
+ * into an AccessTokenGetter by retrying the unreliable getter in a regular
1604
+ * interval.
1605
+ *
1606
+ * @param getAccessToken - a function that produces a promise of an access
1607
+ * token that may fail by returning null
1608
+ * @param retryIntervalInMs - the time (in milliseconds) to wait between retry
1609
+ * attempts
1610
+ * @param timeoutInMs - the timestamp after which the refresh attempt will fail,
1611
+ * throwing an exception
1612
+ * @returns - a promise that, if it resolves, will resolve with an access token
1613
+ */
1614
+ async function beginRefresh(getAccessToken, retryIntervalInMs, timeoutInMs) {
1615
+ // This wrapper handles exceptions gracefully as long as we haven't exceeded
1616
+ // the timeout.
1617
+ async function tryGetAccessToken() {
1618
+ if (Date.now() < timeoutInMs) {
1619
+ try {
1620
+ return await getAccessToken();
1621
+ }
1622
+ catch (_a) {
1623
+ return null;
1624
+ }
1625
+ }
1626
+ else {
1627
+ const finalToken = await getAccessToken();
1628
+ // Timeout is up, so throw if it's still null
1629
+ if (finalToken === null) {
1630
+ throw new Error("Failed to refresh access token.");
1631
+ }
1632
+ return finalToken;
1633
+ }
1634
+ }
1635
+ let token = await tryGetAccessToken();
1636
+ while (token === null) {
1637
+ await coreHttp.delay(retryIntervalInMs);
1638
+ token = await tryGetAccessToken();
1639
+ }
1640
+ return token;
1641
+ }
1642
+ /**
1643
+ * Creates a token cycler from a credential, scopes, and optional settings.
1644
+ *
1645
+ * A token cycler represents a way to reliably retrieve a valid access token
1646
+ * from a TokenCredential. It will handle initializing the token, refreshing it
1647
+ * when it nears expiration, and synchronizes refresh attempts to avoid
1648
+ * concurrency hazards.
1649
+ *
1650
+ * @param credential - the underlying TokenCredential that provides the access
1651
+ * token
1652
+ * @param scopes - the scopes to request authorization for
1653
+ * @param tokenCyclerOptions - optionally override default settings for the cycler
1654
+ *
1655
+ * @returns - a function that reliably produces a valid access token
1656
+ */
1657
+ function createTokenCycler(credential, scopes, tokenCyclerOptions) {
1658
+ let refreshWorker = null;
1659
+ let token = null;
1660
+ const options = Object.assign(Object.assign({}, DEFAULT_CYCLER_OPTIONS), tokenCyclerOptions);
1661
+ /**
1662
+ * This little holder defines several predicates that we use to construct
1663
+ * the rules of refreshing the token.
1664
+ */
1665
+ const cycler = {
1666
+ /**
1667
+ * Produces true if a refresh job is currently in progress.
1668
+ */
1669
+ get isRefreshing() {
1670
+ return refreshWorker !== null;
1671
+ },
1672
+ /**
1673
+ * Produces true if the cycler SHOULD refresh (we are within the refresh
1674
+ * window and not already refreshing)
1675
+ */
1676
+ get shouldRefresh() {
1677
+ var _a;
1678
+ return (!cycler.isRefreshing &&
1679
+ ((_a = token === null || token === void 0 ? void 0 : token.expiresOnTimestamp) !== null && _a !== void 0 ? _a : 0) - options.refreshWindowInMs < Date.now());
1680
+ },
1681
+ /**
1682
+ * Produces true if the cycler MUST refresh (null or nearly-expired
1683
+ * token).
1684
+ */
1685
+ get mustRefresh() {
1686
+ return (token === null || token.expiresOnTimestamp - options.forcedRefreshWindowInMs < Date.now());
1687
+ },
1688
+ };
1689
+ /**
1690
+ * Starts a refresh job or returns the existing job if one is already
1691
+ * running.
1692
+ */
1693
+ function refresh(getTokenOptions) {
1694
+ var _a;
1695
+ if (!cycler.isRefreshing) {
1696
+ // We bind `scopes` here to avoid passing it around a lot
1697
+ const tryGetAccessToken = () => credential.getToken(scopes, getTokenOptions);
1698
+ // Take advantage of promise chaining to insert an assignment to `token`
1699
+ // before the refresh can be considered done.
1700
+ refreshWorker = beginRefresh(tryGetAccessToken, options.retryIntervalInMs,
1701
+ // If we don't have a token, then we should timeout immediately
1702
+ (_a = token === null || token === void 0 ? void 0 : token.expiresOnTimestamp) !== null && _a !== void 0 ? _a : Date.now())
1703
+ .then((_token) => {
1704
+ refreshWorker = null;
1705
+ token = _token;
1706
+ return token;
1707
+ })
1708
+ .catch((reason) => {
1709
+ // We also should reset the refresher if we enter a failed state. All
1710
+ // existing awaiters will throw, but subsequent requests will start a
1711
+ // new retry chain.
1712
+ refreshWorker = null;
1713
+ token = null;
1714
+ throw reason;
1715
+ });
1716
+ }
1717
+ return refreshWorker;
1718
+ }
1719
+ return async (tokenOptions) => {
1720
+ //
1721
+ // Simple rules:
1722
+ // - If we MUST refresh, then return the refresh task, blocking
1723
+ // the pipeline until a token is available.
1724
+ // - If we SHOULD refresh, then run refresh but don't return it
1725
+ // (we can still use the cached token).
1726
+ // - Return the token, since it's fine if we didn't return in
1727
+ // step 1.
1728
+ //
1729
+ if (cycler.mustRefresh)
1730
+ return refresh(tokenOptions);
1731
+ if (cycler.shouldRefresh) {
1732
+ refresh(tokenOptions);
1733
+ }
1734
+ return token;
1735
+ };
1736
+ }
1737
+ /**
1738
+ * We will retrieve the challenge only if the response status code was 401,
1739
+ * and if the response contained the header "WWW-Authenticate" with a non-empty value.
1740
+ */
1741
+ function getChallenge(response) {
1742
+ const challenge = response.headers.get("WWW-Authenticate");
1743
+ if (response.status === 401 && challenge) {
1744
+ return challenge;
1745
+ }
1746
+ return;
1747
+ }
1748
+ /**
1749
+ * Converts: `Bearer a="b" c="d"`.
1750
+ * Into: `[ { a: 'b', c: 'd' }]`.
1751
+ *
1752
+ * @internal
1753
+ */
1754
+ function parseChallenge(challenge) {
1755
+ const bearerChallenge = challenge.slice("Bearer ".length);
1756
+ const challengeParts = `${bearerChallenge.trim()} `.split(" ").filter((x) => x);
1757
+ const keyValuePairs = challengeParts.map((keyValue) => (([key, value]) => ({ [key]: value }))(keyValue.trim().split("=")));
1758
+ // Key-value pairs to plain object:
1759
+ return keyValuePairs.reduce((a, b) => (Object.assign(Object.assign({}, a), b)), {});
1760
+ }
1761
+ // #endregion
1762
+ /**
1763
+ * Creates a new factory for a RequestPolicy that applies a bearer token to
1764
+ * the requests' `Authorization` headers.
1765
+ *
1766
+ * @param credential - The TokenCredential implementation that can supply the bearer token.
1767
+ * @param scopes - The scopes for which the bearer token applies.
1768
+ */
1769
+ function storageBearerTokenChallengeAuthenticationPolicy(credential, scopes) {
1770
+ // This simple function encapsulates the entire process of reliably retrieving the token
1771
+ let getToken = createTokenCycler(credential, scopes);
1772
+ class StorageBearerTokenChallengeAuthenticationPolicy extends coreHttp.BaseRequestPolicy {
1773
+ constructor(nextPolicy, options) {
1774
+ super(nextPolicy, options);
1775
+ }
1776
+ async sendRequest(webResource) {
1777
+ if (!webResource.url.toLowerCase().startsWith("https://")) {
1778
+ throw new Error("Bearer token authentication is not permitted for non-TLS protected (non-https) URLs.");
1779
+ }
1780
+ const getTokenInternal = getToken;
1781
+ const token = (await getTokenInternal({
1782
+ abortSignal: webResource.abortSignal,
1783
+ tracingOptions: {
1784
+ tracingContext: webResource.tracingContext,
1785
+ },
1786
+ })).token;
1787
+ webResource.headers.set(Constants.HeaderConstants.AUTHORIZATION, `Bearer ${token}`);
1788
+ const response = await this._nextPolicy.sendRequest(webResource);
1789
+ if ((response === null || response === void 0 ? void 0 : response.status) === 401) {
1790
+ const challenge = getChallenge(response);
1791
+ if (challenge) {
1792
+ const challengeInfo = parseChallenge(challenge);
1793
+ const challengeScopes = challengeInfo.resource_id + Constants.DefaultScope;
1794
+ const parsedAuthUri = coreHttp.URLBuilder.parse(challengeInfo.authorization_uri);
1795
+ const pathSegments = parsedAuthUri.getPath().split("/");
1796
+ const tenantId = pathSegments[1];
1797
+ const getTokenForChallenge = createTokenCycler(credential, challengeScopes);
1798
+ const tokenForChallenge = (await getTokenForChallenge({
1799
+ abortSignal: webResource.abortSignal,
1800
+ tracingOptions: {
1801
+ tracingContext: webResource.tracingContext,
1802
+ },
1803
+ tenantId: tenantId,
1804
+ })).token;
1805
+ getToken = getTokenForChallenge;
1806
+ webResource.headers.set(Constants.HeaderConstants.AUTHORIZATION, `Bearer ${tokenForChallenge}`);
1807
+ return this._nextPolicy.sendRequest(webResource);
1808
+ }
1809
+ }
1810
+ return response;
1811
+ }
1812
+ }
1813
+ return {
1814
+ create: (nextPolicy, options) => {
1815
+ return new StorageBearerTokenChallengeAuthenticationPolicy(nextPolicy, options);
1816
+ },
1817
+ };
1818
+ }
1819
+
1579
1820
  // Copyright (c) Microsoft Corporation.
1580
1821
  /**
1581
1822
  * A Pipeline class containing HTTP request policies.
@@ -1618,6 +1859,7 @@ class Pipeline {
1618
1859
  * @returns A new Pipeline object.
1619
1860
  */
1620
1861
  function newPipeline(credential, pipelineOptions = {}) {
1862
+ var _a;
1621
1863
  if (credential === undefined) {
1622
1864
  credential = new AnonymousCredential();
1623
1865
  }
@@ -1644,11 +1886,27 @@ function newPipeline(credential, pipelineOptions = {}) {
1644
1886
  factories.push(coreHttp.proxyPolicy(pipelineOptions.proxyOptions));
1645
1887
  }
1646
1888
  factories.push(coreHttp.isTokenCredential(credential)
1647
- ? coreHttp.bearerTokenAuthenticationPolicy(credential, StorageOAuthScopes)
1889
+ ? storageBearerTokenChallengeAuthenticationPolicy(credential, (_a = pipelineOptions.audience) !== null && _a !== void 0 ? _a : StorageOAuthScopes)
1648
1890
  : credential);
1649
1891
  return new Pipeline(factories, pipelineOptions);
1650
1892
  }
1651
1893
 
1894
+ // Copyright (c) Microsoft Corporation.
1895
+ // Licensed under the MIT license.
1896
+ /**
1897
+ * Defines the known cloud audiences for Storage.
1898
+ */
1899
+ exports.StorageQueueAudience = void 0;
1900
+ (function (StorageQueueAudience) {
1901
+ /**
1902
+ * The OAuth scope to use to retrieve an AAD token for Azure Storage.
1903
+ */
1904
+ StorageQueueAudience["StorageOAuthScopes"] = "https://storage.azure.com/.default";
1905
+ })(exports.StorageQueueAudience || (exports.StorageQueueAudience = {}));
1906
+ function getQueueServiceAccountAudience(storageAccountName) {
1907
+ return `https://${storageAccountName}.queue.core.windows.net/.default`;
1908
+ }
1909
+
1652
1910
  /*
1653
1911
  * Copyright (c) Microsoft Corporation.
1654
1912
  * Licensed under the MIT License.
@@ -3495,7 +3753,7 @@ const timeoutInSeconds = {
3495
3753
  const version = {
3496
3754
  parameterPath: "version",
3497
3755
  mapper: {
3498
- defaultValue: "2023-08-03",
3756
+ defaultValue: "2023-11-03",
3499
3757
  isConstant: true,
3500
3758
  serializedName: "x-ms-version",
3501
3759
  type: {
@@ -5850,6 +6108,7 @@ exports.StorageSharedKeyCredential = StorageSharedKeyCredential;
5850
6108
  exports.StorageSharedKeyCredentialPolicy = StorageSharedKeyCredentialPolicy;
5851
6109
  exports.generateAccountSASQueryParameters = generateAccountSASQueryParameters;
5852
6110
  exports.generateQueueSASQueryParameters = generateQueueSASQueryParameters;
6111
+ exports.getQueueServiceAccountAudience = getQueueServiceAccountAudience;
5853
6112
  exports.logger = logger;
5854
6113
  exports.newPipeline = newPipeline;
5855
6114
  //# sourceMappingURL=index.js.map