@azure/core-client 1.6.0-alpha.20220422.1 → 1.6.0

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,11 +1,12 @@
1
1
  # Release History
2
2
 
3
- ## 1.6.0 (unreleased)
3
+ ## 1.6.0 (2022-05-05)
4
4
 
5
5
  ### Features Added
6
6
 
7
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)
8
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)
9
10
 
10
11
  ## 1.5.0 (2022-02-03)
11
12
 
package/dist/index.js CHANGED
@@ -2008,11 +2008,111 @@ async function authorizeRequestOnClaimChallenge(onChallengeOptions) {
2008
2008
  return true;
2009
2009
  }
2010
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
+
2011
2110
  exports.MapperTypeNames = MapperTypeNames;
2012
2111
  exports.ServiceClient = ServiceClient;
2013
2112
  exports.XML_ATTRKEY = XML_ATTRKEY;
2014
2113
  exports.XML_CHARKEY = XML_CHARKEY;
2015
2114
  exports.authorizeRequestOnClaimChallenge = authorizeRequestOnClaimChallenge;
2115
+ exports.authorizeRequestOnTenantChallenge = authorizeRequestOnTenantChallenge;
2016
2116
  exports.createClientPipeline = createClientPipeline;
2017
2117
  exports.createSerializer = createSerializer;
2018
2118
  exports.deserializationPolicy = deserializationPolicy;