@azure/core-client 1.6.0-alpha.20220420.2 → 1.6.0-alpha.20220503.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/CHANGELOG.md CHANGED
@@ -1,16 +1,12 @@
1
1
  # Release History
2
2
 
3
- ## 1.6.0 (Unreleased)
3
+ ## 1.6.0 (unreleased)
4
4
 
5
5
  ### Features Added
6
6
 
7
- ### Breaking Changes
8
-
9
- ### Bugs Fixed
10
-
11
- ### Other Changes
12
-
7
+ - Added a new property endpoint in ServiceClientOptions and mark the baseUri as deprecated to encourage people to use endpoint. See issue link [here](https://github.com/Azure/autorest.typescript/issues/1337)
13
8
  - Upgraded our `@azure/core-tracing` dependency to version 1.0
9
+ - Add callbacks to support Storage challenge authentication [PR#21678](https://github.com/Azure/azure-sdk-for-js/pull/21678)
14
10
 
15
11
  ## 1.5.0 (2022-02-03)
16
12
 
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var coreRestPipeline = require('@azure/core-rest-pipeline');
6
- var logger = require('@azure/logger');
6
+ var logger$1 = require('@azure/logger');
7
7
 
8
8
  // Copyright (c) Microsoft Corporation.
9
9
  /**
@@ -1796,6 +1796,9 @@ function appendQueryParams(url, queryParams, sequenceParams, noOverwrite = false
1796
1796
  return parsedUrl.toString();
1797
1797
  }
1798
1798
 
1799
+ // Copyright (c) Microsoft Corporation.
1800
+ const logger = logger$1.createClientLogger("core-client");
1801
+
1799
1802
  // Copyright (c) Microsoft Corporation.
1800
1803
  /**
1801
1804
  * Initializes a new instance of the ServiceClient.
@@ -1807,13 +1810,16 @@ class ServiceClient {
1807
1810
  * @param options - The service client options that govern the behavior of the client.
1808
1811
  */
1809
1812
  constructor(options = {}) {
1810
- var _a;
1813
+ var _a, _b;
1811
1814
  this._requestContentType = options.requestContentType;
1812
- this._baseUri = options.baseUri;
1815
+ this._endpoint = (_a = options.endpoint) !== null && _a !== void 0 ? _a : options.baseUri;
1816
+ if (options.baseUri) {
1817
+ logger.warning("The baseUri option for SDK Clients has been deprecated, please use endpoint instead.");
1818
+ }
1813
1819
  this._allowInsecureConnection = options.allowInsecureConnection;
1814
1820
  this._httpClient = options.httpClient || getCachedDefaultHttpClient();
1815
1821
  this.pipeline = options.pipeline || createDefaultPipeline(options);
1816
- if ((_a = options.additionalPolicies) === null || _a === void 0 ? void 0 : _a.length) {
1822
+ if ((_b = options.additionalPolicies) === null || _b === void 0 ? void 0 : _b.length) {
1817
1823
  for (const { policy, position } of options.additionalPolicies) {
1818
1824
  // Sign happens after Retry and is commonly needed to occur
1819
1825
  // before policies that intercept post-retry.
@@ -1837,14 +1843,14 @@ class ServiceClient {
1837
1843
  * @param operationSpec - The OperationSpec to use to populate the httpRequest.
1838
1844
  */
1839
1845
  async sendOperationRequest(operationArguments, operationSpec) {
1840
- const baseUri = operationSpec.baseUrl || this._baseUri;
1841
- if (!baseUri) {
1842
- throw new Error("If operationSpec.baseUrl is not specified, then the ServiceClient must have a baseUri string property that contains the base URL to use.");
1846
+ const endpoint = operationSpec.baseUrl || this._endpoint;
1847
+ if (!endpoint) {
1848
+ throw new Error("If operationSpec.baseUrl is not specified, then the ServiceClient must have a endpoint string property that contains the base URL to use.");
1843
1849
  }
1844
1850
  // Templatized URLs sometimes reference properties on the ServiceClient child class,
1845
1851
  // so we have to pass `this` below in order to search these properties if they're
1846
1852
  // not part of OperationArguments
1847
- const url = getRequestUrl(baseUri, operationSpec, operationArguments, this);
1853
+ const url = getRequestUrl(endpoint, operationSpec, operationArguments, this);
1848
1854
  const request = coreRestPipeline.createPipelineRequest({
1849
1855
  url,
1850
1856
  });
@@ -1924,17 +1930,19 @@ function getCredentialScopes(options) {
1924
1930
  ? scopes.map((scope) => new URL(scope).toString())
1925
1931
  : new URL(scopes).toString();
1926
1932
  }
1933
+ if (options.endpoint) {
1934
+ return `${options.endpoint}/.default`;
1935
+ }
1927
1936
  if (options.baseUri) {
1928
1937
  return `${options.baseUri}/.default`;
1929
1938
  }
1930
1939
  if (options.credential && !options.credentialScopes) {
1931
- throw new Error(`When using credentials, the ServiceClientOptions must contain either a baseUri or a credentialScopes. Unable to create a bearerTokenAuthenticationPolicy`);
1940
+ throw new Error(`When using credentials, the ServiceClientOptions must contain either a endpoint or a credentialScopes. Unable to create a bearerTokenAuthenticationPolicy`);
1932
1941
  }
1933
1942
  return undefined;
1934
1943
  }
1935
1944
 
1936
1945
  // Copyright (c) Microsoft Corporation.
1937
- const defaultLogger = logger.createClientLogger("authorizeRequestOnClaimChallenge");
1938
1946
  /**
1939
1947
  * Converts: `Bearer a="b", c="d", Bearer d="e", f="g"`.
1940
1948
  * Into: `[ { a: 'b', c: 'd' }, { d: 'e', f: 'g' } ]`.
@@ -1978,16 +1986,16 @@ function parseCAEChallenge(challenges) {
1978
1986
  */
1979
1987
  async function authorizeRequestOnClaimChallenge(onChallengeOptions) {
1980
1988
  const { scopes, response } = onChallengeOptions;
1981
- const logger = onChallengeOptions.logger || defaultLogger;
1989
+ const logger$1 = onChallengeOptions.logger || logger;
1982
1990
  const challenge = response.headers.get("WWW-Authenticate");
1983
1991
  if (!challenge) {
1984
- logger.info(`The WWW-Authenticate header was missing. Failed to perform the Continuous Access Evaluation authentication flow.`);
1992
+ logger$1.info(`The WWW-Authenticate header was missing. Failed to perform the Continuous Access Evaluation authentication flow.`);
1985
1993
  return false;
1986
1994
  }
1987
1995
  const challenges = parseCAEChallenge(challenge) || [];
1988
1996
  const parsedChallenge = challenges.find((x) => x.claims);
1989
1997
  if (!parsedChallenge) {
1990
- logger.info(`The WWW-Authenticate header was missing the necessary "claims" to perform the Continuous Access Evaluation authentication flow.`);
1998
+ logger$1.info(`The WWW-Authenticate header was missing the necessary "claims" to perform the Continuous Access Evaluation authentication flow.`);
1991
1999
  return false;
1992
2000
  }
1993
2001
  const accessToken = await onChallengeOptions.getAccessToken(parsedChallenge.scope ? [parsedChallenge.scope] : scopes, {
@@ -2000,11 +2008,111 @@ async function authorizeRequestOnClaimChallenge(onChallengeOptions) {
2000
2008
  return true;
2001
2009
  }
2002
2010
 
2011
+ // Copyright (c) Microsoft Corporation.
2012
+ // Licensed under the MIT license.
2013
+ /**
2014
+ * A set of constants used internally when processing requests.
2015
+ */
2016
+ const Constants = {
2017
+ DefaultScope: "/.default",
2018
+ /**
2019
+ * Defines constants for use with HTTP headers.
2020
+ */
2021
+ HeaderConstants: {
2022
+ /**
2023
+ * The Authorization header.
2024
+ */
2025
+ AUTHORIZATION: "authorization",
2026
+ },
2027
+ };
2028
+ /**
2029
+ * Defines a callback to handle auth challenge for Storage APIs.
2030
+ * This implements the bearer challenge process described here: https://docs.microsoft.com/rest/api/storageservices/authorize-with-azure-active-directory#bearer-challenge
2031
+ * Handling has specific features for storage that departs to the general AAD challenge docs.
2032
+ **/
2033
+ const authorizeRequestOnTenantChallenge = async (challengeOptions) => {
2034
+ const requestOptions = requestToOptions(challengeOptions.request);
2035
+ const challenge = getChallenge(challengeOptions.response);
2036
+ if (challenge) {
2037
+ const challengeInfo = parseChallenge(challenge);
2038
+ const challengeScopes = buildScopes(challengeOptions, challengeInfo);
2039
+ const tenantId = extractTenantId(challengeInfo);
2040
+ const accessToken = await challengeOptions.getAccessToken(challengeScopes, Object.assign(Object.assign({}, requestOptions), { tenantId }));
2041
+ if (!accessToken) {
2042
+ return false;
2043
+ }
2044
+ challengeOptions.request.headers.set(Constants.HeaderConstants.AUTHORIZATION, `Bearer ${accessToken.token}`);
2045
+ return true;
2046
+ }
2047
+ return false;
2048
+ };
2049
+ /**
2050
+ * Extracts the tenant id from the challenge information
2051
+ * The tenant id is contained in the authorization_uri as the first
2052
+ * path part.
2053
+ */
2054
+ function extractTenantId(challengeInfo) {
2055
+ const parsedAuthUri = new URL(challengeInfo.authorization_uri);
2056
+ const pathSegments = parsedAuthUri.pathname.split("/");
2057
+ const tenantId = pathSegments[1];
2058
+ return tenantId;
2059
+ }
2060
+ /**
2061
+ * Builds the authentication scopes based on the information that comes in the
2062
+ * challenge information. Scopes url is present in the resource_id, if it is empty
2063
+ * we keep using the original scopes.
2064
+ */
2065
+ function buildScopes(challengeOptions, challengeInfo) {
2066
+ if (!challengeInfo.resource_uri) {
2067
+ return challengeOptions.scopes;
2068
+ }
2069
+ const challengeScopes = new URL(challengeInfo.resource_uri);
2070
+ challengeScopes.pathname = Constants.DefaultScope;
2071
+ return [challengeScopes.toString()];
2072
+ }
2073
+ /**
2074
+ * We will retrieve the challenge only if the response status code was 401,
2075
+ * and if the response contained the header "WWW-Authenticate" with a non-empty value.
2076
+ */
2077
+ function getChallenge(response) {
2078
+ const challenge = response.headers.get("WWW-Authenticate");
2079
+ if (response.status === 401 && challenge) {
2080
+ return challenge;
2081
+ }
2082
+ return;
2083
+ }
2084
+ /**
2085
+ * Converts: `Bearer a="b" c="d"`.
2086
+ * Into: `[ { a: 'b', c: 'd' }]`.
2087
+ *
2088
+ * @internal
2089
+ */
2090
+ function parseChallenge(challenge) {
2091
+ const bearerChallenge = challenge.slice("Bearer ".length);
2092
+ const challengeParts = `${bearerChallenge.trim()} `.split(" ").filter((x) => x);
2093
+ const keyValuePairs = challengeParts.map((keyValue) => (([key, value]) => ({ [key]: value }))(keyValue.trim().split("=")));
2094
+ // Key-value pairs to plain object:
2095
+ return keyValuePairs.reduce((a, b) => (Object.assign(Object.assign({}, a), b)), {});
2096
+ }
2097
+ /**
2098
+ * Extracts the options form a Pipeline Request for later re-use
2099
+ */
2100
+ function requestToOptions(request) {
2101
+ return {
2102
+ abortSignal: request.abortSignal,
2103
+ requestOptions: {
2104
+ timeout: request.timeout,
2105
+ },
2106
+ tracingOptions: request.tracingOptions,
2107
+ };
2108
+ }
2109
+
2003
2110
  exports.MapperTypeNames = MapperTypeNames;
2004
2111
  exports.ServiceClient = ServiceClient;
2005
2112
  exports.XML_ATTRKEY = XML_ATTRKEY;
2006
2113
  exports.XML_CHARKEY = XML_CHARKEY;
2007
2114
  exports.authorizeRequestOnClaimChallenge = authorizeRequestOnClaimChallenge;
2115
+ exports.authorizeRequestOnTenantChallenge = authorizeRequestOnTenantChallenge;
2008
2116
  exports.createClientPipeline = createClientPipeline;
2009
2117
  exports.createSerializer = createSerializer;
2010
2118
  exports.deserializationPolicy = deserializationPolicy;