@azure/storage-blob 12.9.0-alpha.20220302.1 → 12.9.0-alpha.20220310.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,16 +1,24 @@
1
1
  # Release History
2
2
 
3
- ## 12.9.0-beta.4 (Unreleased)
3
+ ## 12.9.0 (2022-03-11)
4
4
 
5
5
  ### Features Added
6
6
 
7
- ### Breaking Changes
7
+ - Includes all features released in 12.9.0-beta.1, 12.9.0-beta.2, 12.9.0-beta.3 and 12.9.0-beta.4.
8
8
 
9
9
  ### Bugs Fixed
10
10
 
11
- - Set correct content length in requests for uploading operations to avoid unexpected failure if customized content length is incorrect.
11
+ - Fixed an issue of always sending x-ms-encryption-algorithm header in request.
12
+
13
+ ## 12.9.0-beta.4 (2022-03-04)
14
+
15
+ ### Features Added
12
16
 
13
- ### Other Changes
17
+ - Added ability to specify Disk Compute AAD Audience in StoragePipelineOptions.
18
+
19
+ ### Bugs Fixed
20
+
21
+ - Set correct content length in requests for uploading operations to avoid unexpected failure if customized content length is incorrect.
14
22
 
15
23
  ## 12.9.0-beta.3 (2022-02-11)
16
24
 
package/dist/index.js CHANGED
@@ -9107,10 +9107,10 @@ const encryptionKeySha256 = {
9107
9107
  }
9108
9108
  };
9109
9109
  const encryptionAlgorithm = {
9110
- parameterPath: ["options", "encryptionAlgorithm"],
9110
+ parameterPath: ["options", "cpkInfo", "encryptionAlgorithm"],
9111
9111
  mapper: {
9112
- isConstant: false,
9113
9112
  serializedName: "x-ms-encryption-algorithm",
9113
+ xmlName: "x-ms-encryption-algorithm",
9114
9114
  type: {
9115
9115
  name: "String"
9116
9116
  }
@@ -13301,7 +13301,7 @@ const logger = logger$1.createClientLogger("storage-blob");
13301
13301
 
13302
13302
  // Copyright (c) Microsoft Corporation.
13303
13303
  // Licensed under the MIT license.
13304
- const SDK_VERSION = "12.9.0-beta.4";
13304
+ const SDK_VERSION = "12.9.0";
13305
13305
  const SERVICE_VERSION = "2021-04-10";
13306
13306
  const BLOCK_BLOB_MAX_UPLOAD_BLOB_BYTES = 256 * 1024 * 1024; // 256MB
13307
13307
  const BLOCK_BLOB_MAX_STAGE_BLOCK_BYTES = 4000 * 1024 * 1024; // 4000MB
@@ -14728,6 +14728,247 @@ function getCachedDefaultHttpClient() {
14728
14728
  return _defaultHttpClient;
14729
14729
  }
14730
14730
 
14731
+ // Copyright (c) Microsoft Corporation.
14732
+ /**
14733
+ * A set of constants used internally when processing requests.
14734
+ */
14735
+ const Constants = {
14736
+ DefaultScope: "/.default",
14737
+ /**
14738
+ * Defines constants for use with HTTP headers.
14739
+ */
14740
+ HeaderConstants: {
14741
+ /**
14742
+ * The Authorization header.
14743
+ */
14744
+ AUTHORIZATION: "authorization",
14745
+ },
14746
+ };
14747
+ // Default options for the cycler if none are provided
14748
+ const DEFAULT_CYCLER_OPTIONS = {
14749
+ forcedRefreshWindowInMs: 1000,
14750
+ retryIntervalInMs: 3000,
14751
+ refreshWindowInMs: 1000 * 60 * 2, // Start refreshing 2m before expiry
14752
+ };
14753
+ /**
14754
+ * Converts an an unreliable access token getter (which may resolve with null)
14755
+ * into an AccessTokenGetter by retrying the unreliable getter in a regular
14756
+ * interval.
14757
+ *
14758
+ * @param getAccessToken - a function that produces a promise of an access
14759
+ * token that may fail by returning null
14760
+ * @param retryIntervalInMs - the time (in milliseconds) to wait between retry
14761
+ * attempts
14762
+ * @param timeoutInMs - the timestamp after which the refresh attempt will fail,
14763
+ * throwing an exception
14764
+ * @returns - a promise that, if it resolves, will resolve with an access token
14765
+ */
14766
+ async function beginRefresh(getAccessToken, retryIntervalInMs, timeoutInMs) {
14767
+ // This wrapper handles exceptions gracefully as long as we haven't exceeded
14768
+ // the timeout.
14769
+ async function tryGetAccessToken() {
14770
+ if (Date.now() < timeoutInMs) {
14771
+ try {
14772
+ return await getAccessToken();
14773
+ }
14774
+ catch (_a) {
14775
+ return null;
14776
+ }
14777
+ }
14778
+ else {
14779
+ const finalToken = await getAccessToken();
14780
+ // Timeout is up, so throw if it's still null
14781
+ if (finalToken === null) {
14782
+ throw new Error("Failed to refresh access token.");
14783
+ }
14784
+ return finalToken;
14785
+ }
14786
+ }
14787
+ let token = await tryGetAccessToken();
14788
+ while (token === null) {
14789
+ await coreHttp.delay(retryIntervalInMs);
14790
+ token = await tryGetAccessToken();
14791
+ }
14792
+ return token;
14793
+ }
14794
+ /**
14795
+ * Creates a token cycler from a credential, scopes, and optional settings.
14796
+ *
14797
+ * A token cycler represents a way to reliably retrieve a valid access token
14798
+ * from a TokenCredential. It will handle initializing the token, refreshing it
14799
+ * when it nears expiration, and synchronizes refresh attempts to avoid
14800
+ * concurrency hazards.
14801
+ *
14802
+ * @param credential - the underlying TokenCredential that provides the access
14803
+ * token
14804
+ * @param scopes - the scopes to request authorization for
14805
+ * @param tokenCyclerOptions - optionally override default settings for the cycler
14806
+ *
14807
+ * @returns - a function that reliably produces a valid access token
14808
+ */
14809
+ function createTokenCycler(credential, scopes, tokenCyclerOptions) {
14810
+ let refreshWorker = null;
14811
+ let token = null;
14812
+ const options = Object.assign(Object.assign({}, DEFAULT_CYCLER_OPTIONS), tokenCyclerOptions);
14813
+ /**
14814
+ * This little holder defines several predicates that we use to construct
14815
+ * the rules of refreshing the token.
14816
+ */
14817
+ const cycler = {
14818
+ /**
14819
+ * Produces true if a refresh job is currently in progress.
14820
+ */
14821
+ get isRefreshing() {
14822
+ return refreshWorker !== null;
14823
+ },
14824
+ /**
14825
+ * Produces true if the cycler SHOULD refresh (we are within the refresh
14826
+ * window and not already refreshing)
14827
+ */
14828
+ get shouldRefresh() {
14829
+ var _a;
14830
+ return (!cycler.isRefreshing &&
14831
+ ((_a = token === null || token === void 0 ? void 0 : token.expiresOnTimestamp) !== null && _a !== void 0 ? _a : 0) - options.refreshWindowInMs < Date.now());
14832
+ },
14833
+ /**
14834
+ * Produces true if the cycler MUST refresh (null or nearly-expired
14835
+ * token).
14836
+ */
14837
+ get mustRefresh() {
14838
+ return (token === null || token.expiresOnTimestamp - options.forcedRefreshWindowInMs < Date.now());
14839
+ },
14840
+ };
14841
+ /**
14842
+ * Starts a refresh job or returns the existing job if one is already
14843
+ * running.
14844
+ */
14845
+ function refresh(getTokenOptions) {
14846
+ var _a;
14847
+ if (!cycler.isRefreshing) {
14848
+ // We bind `scopes` here to avoid passing it around a lot
14849
+ const tryGetAccessToken = () => credential.getToken(scopes, getTokenOptions);
14850
+ // Take advantage of promise chaining to insert an assignment to `token`
14851
+ // before the refresh can be considered done.
14852
+ refreshWorker = beginRefresh(tryGetAccessToken, options.retryIntervalInMs,
14853
+ // If we don't have a token, then we should timeout immediately
14854
+ (_a = token === null || token === void 0 ? void 0 : token.expiresOnTimestamp) !== null && _a !== void 0 ? _a : Date.now())
14855
+ .then((_token) => {
14856
+ refreshWorker = null;
14857
+ token = _token;
14858
+ return token;
14859
+ })
14860
+ .catch((reason) => {
14861
+ // We also should reset the refresher if we enter a failed state. All
14862
+ // existing awaiters will throw, but subsequent requests will start a
14863
+ // new retry chain.
14864
+ refreshWorker = null;
14865
+ token = null;
14866
+ throw reason;
14867
+ });
14868
+ }
14869
+ return refreshWorker;
14870
+ }
14871
+ return async (tokenOptions) => {
14872
+ //
14873
+ // Simple rules:
14874
+ // - If we MUST refresh, then return the refresh task, blocking
14875
+ // the pipeline until a token is available.
14876
+ // - If we SHOULD refresh, then run refresh but don't return it
14877
+ // (we can still use the cached token).
14878
+ // - Return the token, since it's fine if we didn't return in
14879
+ // step 1.
14880
+ //
14881
+ if (cycler.mustRefresh)
14882
+ return refresh(tokenOptions);
14883
+ if (cycler.shouldRefresh) {
14884
+ refresh(tokenOptions);
14885
+ }
14886
+ return token;
14887
+ };
14888
+ }
14889
+ /**
14890
+ * We will retrieve the challenge only if the response status code was 401,
14891
+ * and if the response contained the header "WWW-Authenticate" with a non-empty value.
14892
+ */
14893
+ function getChallenge(response) {
14894
+ const challenge = response.headers.get("WWW-Authenticate");
14895
+ if (response.status === 401 && challenge) {
14896
+ return challenge;
14897
+ }
14898
+ return;
14899
+ }
14900
+ /**
14901
+ * Converts: `Bearer a="b" c="d"`.
14902
+ * Into: `[ { a: 'b', c: 'd' }]`.
14903
+ *
14904
+ * @internal
14905
+ */
14906
+ function parseChallenge(challenge) {
14907
+ const bearerChallenge = challenge.slice("Bearer ".length);
14908
+ const challengeParts = `${bearerChallenge.trim()} `.split(" ").filter((x) => x);
14909
+ const keyValuePairs = challengeParts.map((keyValue) => (([key, value]) => ({ [key]: value }))(keyValue.trim().split("=")));
14910
+ // Key-value pairs to plain object:
14911
+ return keyValuePairs.reduce((a, b) => (Object.assign(Object.assign({}, a), b)), {});
14912
+ }
14913
+ // #endregion
14914
+ /**
14915
+ * Creates a new factory for a RequestPolicy that applies a bearer token to
14916
+ * the requests' `Authorization` headers.
14917
+ *
14918
+ * @param credential - The TokenCredential implementation that can supply the bearer token.
14919
+ * @param scopes - The scopes for which the bearer token applies.
14920
+ */
14921
+ function storageBearerTokenChallengeAuthenticationPolicy(credential, scopes) {
14922
+ // This simple function encapsulates the entire process of reliably retrieving the token
14923
+ let getToken = createTokenCycler(credential, scopes);
14924
+ class StorageBearerTokenChallengeAuthenticationPolicy extends coreHttp.BaseRequestPolicy {
14925
+ constructor(nextPolicy, options) {
14926
+ super(nextPolicy, options);
14927
+ }
14928
+ async sendRequest(webResource) {
14929
+ if (!webResource.url.toLowerCase().startsWith("https://")) {
14930
+ throw new Error("Bearer token authentication is not permitted for non-TLS protected (non-https) URLs.");
14931
+ }
14932
+ const getTokenInternal = getToken;
14933
+ const token = (await getTokenInternal({
14934
+ abortSignal: webResource.abortSignal,
14935
+ tracingOptions: {
14936
+ tracingContext: webResource.tracingContext,
14937
+ },
14938
+ })).token;
14939
+ webResource.headers.set(Constants.HeaderConstants.AUTHORIZATION, `Bearer ${token}`);
14940
+ const response = await this._nextPolicy.sendRequest(webResource);
14941
+ if ((response === null || response === void 0 ? void 0 : response.status) === 401) {
14942
+ const challenge = getChallenge(response);
14943
+ if (challenge) {
14944
+ const challengeInfo = parseChallenge(challenge);
14945
+ const challengeScopes = challengeInfo.resource_id + Constants.DefaultScope;
14946
+ const parsedAuthUri = coreHttp.URLBuilder.parse(challengeInfo.authorization_uri);
14947
+ const pathSegments = parsedAuthUri.getPath().split("/");
14948
+ const tenantId = pathSegments[1];
14949
+ const getTokenForChallenge = createTokenCycler(credential, challengeScopes);
14950
+ const tokenForChallenge = (await getTokenForChallenge({
14951
+ abortSignal: webResource.abortSignal,
14952
+ tracingOptions: {
14953
+ tracingContext: webResource.tracingContext,
14954
+ },
14955
+ tenantId: tenantId,
14956
+ })).token;
14957
+ getToken = getTokenForChallenge;
14958
+ webResource.headers.set(Constants.HeaderConstants.AUTHORIZATION, `Bearer ${tokenForChallenge}`);
14959
+ return this._nextPolicy.sendRequest(webResource);
14960
+ }
14961
+ }
14962
+ return response;
14963
+ }
14964
+ }
14965
+ return {
14966
+ create: (nextPolicy, options) => {
14967
+ return new StorageBearerTokenChallengeAuthenticationPolicy(nextPolicy, options);
14968
+ },
14969
+ };
14970
+ }
14971
+
14731
14972
  // Copyright (c) Microsoft Corporation.
14732
14973
  /**
14733
14974
  * A helper to decide if a given argument satisfies the Pipeline contract
@@ -14785,6 +15026,7 @@ class Pipeline {
14785
15026
  * @returns A new Pipeline object.
14786
15027
  */
14787
15028
  function newPipeline(credential, pipelineOptions = {}) {
15029
+ var _a;
14788
15030
  if (credential === undefined) {
14789
15031
  credential = new AnonymousCredential();
14790
15032
  }
@@ -14815,7 +15057,7 @@ function newPipeline(credential, pipelineOptions = {}) {
14815
15057
  factories.push(coreHttp.disableResponseDecompressionPolicy());
14816
15058
  }
14817
15059
  factories.push(coreHttp.isTokenCredential(credential)
14818
- ? attachCredential(coreHttp.bearerTokenAuthenticationPolicy(credential, StorageOAuthScopes), credential)
15060
+ ? attachCredential(storageBearerTokenChallengeAuthenticationPolicy(credential, (_a = pipelineOptions.audience) !== null && _a !== void 0 ? _a : StorageOAuthScopes), credential)
14819
15061
  : credential);
14820
15062
  return new Pipeline(factories, pipelineOptions);
14821
15063
  }
@@ -15000,7 +15242,7 @@ class StorageSharedKeyCredential extends Credential {
15000
15242
  * Changes may cause incorrect behavior and will be lost if the code is regenerated.
15001
15243
  */
15002
15244
  const packageName = "azure-storage-blob";
15003
- const packageVersion = "12.9.0-beta.4";
15245
+ const packageVersion = "12.9.0";
15004
15246
  class StorageClientContext extends coreHttp__namespace.ServiceClient {
15005
15247
  /**
15006
15248
  * Initializes a new instance of the StorageClientContext class.
@@ -18179,6 +18421,20 @@ function ensureCpkIfSpecified(cpk, isHttps) {
18179
18421
  cpk.encryptionAlgorithm = EncryptionAlgorithmAES25;
18180
18422
  }
18181
18423
  }
18424
+ /**
18425
+ * Defines the known cloud audiences for Storage.
18426
+ */
18427
+ exports.StorageBlobAudience = void 0;
18428
+ (function (StorageBlobAudience) {
18429
+ /**
18430
+ * The OAuth scope to use to retrieve an AAD token for Azure Storage.
18431
+ */
18432
+ StorageBlobAudience["StorageOAuthScopes"] = "https://storage.azure.com/.default";
18433
+ /**
18434
+ * The OAuth scope to use to retrieve an AAD token for Azure Disk.
18435
+ */
18436
+ StorageBlobAudience["DiskComputeOAuthScopes"] = "https://disk.compute.azure.com/.default";
18437
+ })(exports.StorageBlobAudience || (exports.StorageBlobAudience = {}));
18182
18438
 
18183
18439
  // Copyright (c) Microsoft Corporation.
18184
18440
  // Licensed under the MIT license.