@azure/core-client 1.3.3 → 1.4.0-alpha.20220104.5
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 +13 -0
- package/dist/index.js +125 -32
- package/dist/index.js.map +1 -1
- package/dist-esm/src/authorizeRequestOnClaimChallenge.js +70 -0
- package/dist-esm/src/authorizeRequestOnClaimChallenge.js.map +1 -0
- package/dist-esm/src/base64.browser.js +7 -0
- package/dist-esm/src/base64.browser.js.map +1 -1
- package/dist-esm/src/base64.js +8 -0
- package/dist-esm/src/base64.js.map +1 -1
- package/dist-esm/src/deserializationPolicy.js +10 -9
- package/dist-esm/src/deserializationPolicy.js.map +1 -1
- package/dist-esm/src/index.js +4 -3
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/interfaces.js.map +1 -1
- package/dist-esm/src/operationHelpers.js +1 -1
- package/dist-esm/src/operationHelpers.js.map +1 -1
- package/dist-esm/src/pipeline.js +3 -3
- package/dist-esm/src/pipeline.js.map +1 -1
- package/dist-esm/src/serializationPolicy.js +7 -7
- package/dist-esm/src/serializationPolicy.js.map +1 -1
- package/dist-esm/src/serializer.js +29 -14
- package/dist-esm/src/serializer.js.map +1 -1
- package/dist-esm/src/serviceClient.js +2 -2
- package/dist-esm/src/serviceClient.js.map +1 -1
- package/dist-esm/src/urlHelpers.js +2 -2
- package/dist-esm/src/urlHelpers.js.map +1 -1
- package/dist-esm/src/utils.js +1 -1
- package/dist-esm/src/utils.js.map +1 -1
- package/package.json +8 -9
- package/types/3.1/core-client.d.ts +205 -2
- package/types/latest/core-client.d.ts +206 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
+
## 1.4.0 (Unreleased)
|
|
4
|
+
|
|
5
|
+
### Features Added
|
|
6
|
+
|
|
7
|
+
- Added a new function `authorizeRequestOnClaimChallenge`, that can be used with the `@azure/core-rest-pipeline`'s `bearerTokenAuthenticationPolicy` to support [Continuous Access Evaluation (CAE) challenges](https://docs.microsoft.com/azure/active-directory/conditional-access/concept-continuous-access-evaluation).
|
|
8
|
+
- Call the `bearerTokenAuthenticationPolicy` with the following options: `bearerTokenAuthenticationPolicy({ authorizeRequestOnChallenge: authorizeRequestOnClaimChallenge })`. Once provided, the `bearerTokenAuthenticationPolicy` policy will internally handle Continuous Access Evaluation (CAE) challenges. When it can't complete a challenge it will return the 401 (unauthorized) response from ARM.
|
|
9
|
+
|
|
10
|
+
### Breaking Changes
|
|
11
|
+
|
|
12
|
+
### Bugs Fixed
|
|
13
|
+
|
|
14
|
+
### Other Changes
|
|
15
|
+
|
|
3
16
|
## 1.3.3 (2021-12-02)
|
|
4
17
|
|
|
5
18
|
### Bugs Fixed
|
package/dist/index.js
CHANGED
|
@@ -3,6 +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
7
|
require('@azure/core-asynciterator-polyfill');
|
|
7
8
|
|
|
8
9
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -116,7 +117,7 @@ function flattenResponse(fullResponse, responseSpec) {
|
|
|
116
117
|
body: fullResponse.parsedBody,
|
|
117
118
|
headers: parsedHeaders,
|
|
118
119
|
hasNullableType: isNullable,
|
|
119
|
-
shouldWrapBody: isPrimitiveBody(fullResponse.parsedBody, expectedBodyTypeName)
|
|
120
|
+
shouldWrapBody: isPrimitiveBody(fullResponse.parsedBody, expectedBodyTypeName),
|
|
120
121
|
});
|
|
121
122
|
}
|
|
122
123
|
|
|
@@ -140,6 +141,14 @@ function encodeByteArray(value) {
|
|
|
140
141
|
function decodeString(value) {
|
|
141
142
|
return Buffer.from(value, "base64");
|
|
142
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Decodes a base64 string into a string.
|
|
146
|
+
* @param value - the base64 string to decode
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
function decodeStringToString(value) {
|
|
150
|
+
return Buffer.from(value, "base64").toString();
|
|
151
|
+
}
|
|
143
152
|
|
|
144
153
|
// Copyright (c) Microsoft Corporation.
|
|
145
154
|
// Licensed under the MIT license.
|
|
@@ -163,7 +172,7 @@ class SerializerImpl {
|
|
|
163
172
|
throw new Error(`"${objectName}" with value "${value}" should satisfy the constraint "${constraintName}": ${constraintValue}.`);
|
|
164
173
|
};
|
|
165
174
|
if (mapper.constraints && value !== undefined && value !== null) {
|
|
166
|
-
const { ExclusiveMaximum, ExclusiveMinimum, InclusiveMaximum, InclusiveMinimum, MaxItems, MaxLength, MinItems, MinLength, MultipleOf, Pattern, UniqueItems } = mapper.constraints;
|
|
175
|
+
const { ExclusiveMaximum, ExclusiveMinimum, InclusiveMaximum, InclusiveMinimum, MaxItems, MaxLength, MinItems, MinLength, MultipleOf, Pattern, UniqueItems, } = mapper.constraints;
|
|
167
176
|
if (ExclusiveMaximum !== undefined && value >= ExclusiveMaximum) {
|
|
168
177
|
failValidation("ExclusiveMaximum", ExclusiveMaximum);
|
|
169
178
|
}
|
|
@@ -222,8 +231,8 @@ class SerializerImpl {
|
|
|
222
231
|
xml: {
|
|
223
232
|
rootName: (_a = options.xml.rootName) !== null && _a !== void 0 ? _a : "",
|
|
224
233
|
includeRoot: (_b = options.xml.includeRoot) !== null && _b !== void 0 ? _b : false,
|
|
225
|
-
xmlCharKey: (_c = options.xml.xmlCharKey) !== null && _c !== void 0 ? _c : XML_CHARKEY
|
|
226
|
-
}
|
|
234
|
+
xmlCharKey: (_c = options.xml.xmlCharKey) !== null && _c !== void 0 ? _c : XML_CHARKEY,
|
|
235
|
+
},
|
|
227
236
|
};
|
|
228
237
|
let payload = {};
|
|
229
238
|
const mapperType = mapper.type.name;
|
|
@@ -311,8 +320,8 @@ class SerializerImpl {
|
|
|
311
320
|
xml: {
|
|
312
321
|
rootName: (_a = options.xml.rootName) !== null && _a !== void 0 ? _a : "",
|
|
313
322
|
includeRoot: (_b = options.xml.includeRoot) !== null && _b !== void 0 ? _b : false,
|
|
314
|
-
xmlCharKey: (_c = options.xml.xmlCharKey) !== null && _c !== void 0 ? _c : XML_CHARKEY
|
|
315
|
-
}
|
|
323
|
+
xmlCharKey: (_c = options.xml.xmlCharKey) !== null && _c !== void 0 ? _c : XML_CHARKEY,
|
|
324
|
+
},
|
|
316
325
|
};
|
|
317
326
|
if (responseBody === undefined || responseBody === null) {
|
|
318
327
|
if (this.isXML && mapper.type.name === "Sequence" && !mapper.xmlIsWrapped) {
|
|
@@ -417,9 +426,7 @@ function bufferToBase64Url(buffer) {
|
|
|
417
426
|
// Uint8Array to Base64.
|
|
418
427
|
const str = encodeByteArray(buffer);
|
|
419
428
|
// Base64 to Base64Url.
|
|
420
|
-
return trimEnd(str, "=")
|
|
421
|
-
.replace(/\+/g, "-")
|
|
422
|
-
.replace(/\//g, "_");
|
|
429
|
+
return trimEnd(str, "=").replace(/\+/g, "-").replace(/\//g, "_");
|
|
423
430
|
}
|
|
424
431
|
function base64UrlToByteArray(str) {
|
|
425
432
|
if (!str) {
|
|
@@ -578,14 +585,21 @@ function serializeDateTypes(typeName, value, objectName) {
|
|
|
578
585
|
return value;
|
|
579
586
|
}
|
|
580
587
|
function serializeSequenceType(serializer, mapper, object, objectName, isXml, options) {
|
|
588
|
+
var _a;
|
|
581
589
|
if (!Array.isArray(object)) {
|
|
582
590
|
throw new Error(`${objectName} must be of type Array.`);
|
|
583
591
|
}
|
|
584
|
-
|
|
592
|
+
let elementType = mapper.type.element;
|
|
585
593
|
if (!elementType || typeof elementType !== "object") {
|
|
586
594
|
throw new Error(`element" metadata for an Array must be defined in the ` +
|
|
587
595
|
`mapper and it must of type "object" in ${objectName}.`);
|
|
588
596
|
}
|
|
597
|
+
// Quirk: Composite mappers referenced by `element` might
|
|
598
|
+
// not have *all* properties declared (like uberParent),
|
|
599
|
+
// so let's try to look up the full definition by name.
|
|
600
|
+
if (elementType.type.name === "Composite" && elementType.type.className) {
|
|
601
|
+
elementType = (_a = serializer.modelMappers[elementType.type.className]) !== null && _a !== void 0 ? _a : elementType;
|
|
602
|
+
}
|
|
589
603
|
const tempArray = [];
|
|
590
604
|
for (let i = 0; i < object.length; i++) {
|
|
591
605
|
const serializedValue = serializer.serialize(elementType, object[i], objectName, options);
|
|
@@ -941,8 +955,8 @@ function deserializeDictionaryType(serializer, mapper, responseBody, objectName,
|
|
|
941
955
|
return responseBody;
|
|
942
956
|
}
|
|
943
957
|
function deserializeSequenceType(serializer, mapper, responseBody, objectName, options) {
|
|
944
|
-
|
|
945
|
-
|
|
958
|
+
var _a;
|
|
959
|
+
let element = mapper.type.element;
|
|
946
960
|
if (!element || typeof element !== "object") {
|
|
947
961
|
throw new Error(`element" metadata for an Array must be defined in the ` +
|
|
948
962
|
`mapper and it must of type "object" in ${objectName}`);
|
|
@@ -952,6 +966,12 @@ function deserializeSequenceType(serializer, mapper, responseBody, objectName, o
|
|
|
952
966
|
// xml2js will interpret a single element array as just the element, so force it to be an array
|
|
953
967
|
responseBody = [responseBody];
|
|
954
968
|
}
|
|
969
|
+
// Quirk: Composite mappers referenced by `element` might
|
|
970
|
+
// not have *all* properties declared (like uberParent),
|
|
971
|
+
// so let's try to look up the full definition by name.
|
|
972
|
+
if (element.type.name === "Composite" && element.type.className) {
|
|
973
|
+
element = (_a = serializer.modelMappers[element.type.className]) !== null && _a !== void 0 ? _a : element;
|
|
974
|
+
}
|
|
955
975
|
const tempArray = [];
|
|
956
976
|
for (let i = 0; i < responseBody.length; i++) {
|
|
957
977
|
tempArray[i] = serializer.deserialize(element, responseBody[i], `${objectName}[${i}]`, options);
|
|
@@ -963,8 +983,12 @@ function deserializeSequenceType(serializer, mapper, responseBody, objectName, o
|
|
|
963
983
|
function getPolymorphicMapper(serializer, mapper, object, polymorphicPropertyName) {
|
|
964
984
|
const polymorphicDiscriminator = getPolymorphicDiscriminatorRecursively(serializer, mapper);
|
|
965
985
|
if (polymorphicDiscriminator) {
|
|
966
|
-
|
|
986
|
+
let discriminatorName = polymorphicDiscriminator[polymorphicPropertyName];
|
|
967
987
|
if (discriminatorName) {
|
|
988
|
+
// The serializedName might have \\, which we just want to ignore
|
|
989
|
+
if (polymorphicPropertyName === "serializedName") {
|
|
990
|
+
discriminatorName = discriminatorName.replace(/\\/gi, "");
|
|
991
|
+
}
|
|
968
992
|
const discriminatorValue = object[discriminatorName];
|
|
969
993
|
if (discriminatorValue !== undefined && discriminatorValue !== null) {
|
|
970
994
|
const typeName = mapper.type.uberParent || mapper.type.className;
|
|
@@ -1009,7 +1033,7 @@ const MapperTypeNames = {
|
|
|
1009
1033
|
String: "String",
|
|
1010
1034
|
Stream: "Stream",
|
|
1011
1035
|
TimeSpan: "TimeSpan",
|
|
1012
|
-
UnixTime: "UnixTime"
|
|
1036
|
+
UnixTime: "UnixTime",
|
|
1013
1037
|
};
|
|
1014
1038
|
|
|
1015
1039
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -1095,7 +1119,7 @@ function getOperationArgumentValueFromParameter(operationArguments, parameter, f
|
|
|
1095
1119
|
const propertyPath = parameterPath[propertyName];
|
|
1096
1120
|
const propertyValue = getOperationArgumentValueFromParameter(operationArguments, {
|
|
1097
1121
|
parameterPath: propertyPath,
|
|
1098
|
-
mapper: propertyMapper
|
|
1122
|
+
mapper: propertyMapper,
|
|
1099
1123
|
}, fallbackObject);
|
|
1100
1124
|
if (propertyValue !== undefined) {
|
|
1101
1125
|
if (!value) {
|
|
@@ -1141,7 +1165,7 @@ const CollectionFormatToDelimiterMap = {
|
|
|
1141
1165
|
SSV: " ",
|
|
1142
1166
|
Multi: "Multi",
|
|
1143
1167
|
TSV: "\t",
|
|
1144
|
-
Pipes: "|"
|
|
1168
|
+
Pipes: "|",
|
|
1145
1169
|
};
|
|
1146
1170
|
function getRequestUrl(baseUri, operationSpec, operationArguments, fallbackObject) {
|
|
1147
1171
|
const urlReplacements = calculateUrlReplacements(operationSpec, operationArguments, fallbackObject);
|
|
@@ -1276,7 +1300,7 @@ function calculateQueryParameters(operationSpec, operationArguments, fallbackObj
|
|
|
1276
1300
|
}
|
|
1277
1301
|
return {
|
|
1278
1302
|
queryParams: result,
|
|
1279
|
-
sequenceParams
|
|
1303
|
+
sequenceParams,
|
|
1280
1304
|
};
|
|
1281
1305
|
}
|
|
1282
1306
|
function simpleParseQueryParams(queryString) {
|
|
@@ -1390,15 +1414,15 @@ function deserializationPolicy(options = {}) {
|
|
|
1390
1414
|
xml: {
|
|
1391
1415
|
rootName: (_e = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.rootName) !== null && _e !== void 0 ? _e : "",
|
|
1392
1416
|
includeRoot: (_f = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.includeRoot) !== null && _f !== void 0 ? _f : false,
|
|
1393
|
-
xmlCharKey: (_g = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.xmlCharKey) !== null && _g !== void 0 ? _g : XML_CHARKEY
|
|
1394
|
-
}
|
|
1417
|
+
xmlCharKey: (_g = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.xmlCharKey) !== null && _g !== void 0 ? _g : XML_CHARKEY,
|
|
1418
|
+
},
|
|
1395
1419
|
};
|
|
1396
1420
|
return {
|
|
1397
1421
|
name: deserializationPolicyName,
|
|
1398
1422
|
async sendRequest(request, next) {
|
|
1399
1423
|
const response = await next(request);
|
|
1400
1424
|
return deserializeResponseBody(jsonContentTypes, xmlContentTypes, response, updatedOptions, parseXML);
|
|
1401
|
-
}
|
|
1425
|
+
},
|
|
1402
1426
|
};
|
|
1403
1427
|
}
|
|
1404
1428
|
function getOperationResponseMap(parsedResponse) {
|
|
@@ -1468,7 +1492,7 @@ async function deserializeResponseBody(jsonContentTypes, xmlContentTypes, respon
|
|
|
1468
1492
|
const restError = new coreRestPipeline.RestError(`Error ${deserializeError} occurred in deserializing the responseBody - ${parsedResponse.bodyAsText}`, {
|
|
1469
1493
|
statusCode: parsedResponse.status,
|
|
1470
1494
|
request: parsedResponse.request,
|
|
1471
|
-
response: parsedResponse
|
|
1495
|
+
response: parsedResponse,
|
|
1472
1496
|
});
|
|
1473
1497
|
throw restError;
|
|
1474
1498
|
}
|
|
@@ -1511,7 +1535,7 @@ function handleErrorResponse(parsedResponse, operationSpec, responseSpec) {
|
|
|
1511
1535
|
const error = new coreRestPipeline.RestError(initialErrorMessage, {
|
|
1512
1536
|
statusCode: parsedResponse.status,
|
|
1513
1537
|
request: parsedResponse.request,
|
|
1514
|
-
response: parsedResponse
|
|
1538
|
+
response: parsedResponse,
|
|
1515
1539
|
});
|
|
1516
1540
|
// If the item failed but there's no error spec or default spec to deserialize the error,
|
|
1517
1541
|
// we should fail so we just throw the parsed response
|
|
@@ -1548,7 +1572,8 @@ function handleErrorResponse(parsedResponse, operationSpec, responseSpec) {
|
|
|
1548
1572
|
}
|
|
1549
1573
|
// If error response has headers, try to deserialize it using default header mapper
|
|
1550
1574
|
if (parsedResponse.headers && defaultHeadersMapper) {
|
|
1551
|
-
error.response.parsedHeaders =
|
|
1575
|
+
error.response.parsedHeaders =
|
|
1576
|
+
operationSpec.serializer.deserialize(defaultHeadersMapper, parsedResponse.headers.toJSON(), "operationRes.parsedHeaders");
|
|
1552
1577
|
}
|
|
1553
1578
|
}
|
|
1554
1579
|
catch (defaultError) {
|
|
@@ -1587,7 +1612,7 @@ async function parse(jsonContentTypes, xmlContentTypes, operationResponse, opts,
|
|
|
1587
1612
|
code: errCode,
|
|
1588
1613
|
statusCode: operationResponse.status,
|
|
1589
1614
|
request: operationResponse.request,
|
|
1590
|
-
response: operationResponse
|
|
1615
|
+
response: operationResponse,
|
|
1591
1616
|
});
|
|
1592
1617
|
throw e;
|
|
1593
1618
|
}
|
|
@@ -1617,7 +1642,7 @@ function serializationPolicy(options = {}) {
|
|
|
1617
1642
|
serializeRequestBody(request, operationArguments, operationSpec, stringifyXML);
|
|
1618
1643
|
}
|
|
1619
1644
|
return next(request);
|
|
1620
|
-
}
|
|
1645
|
+
},
|
|
1621
1646
|
};
|
|
1622
1647
|
}
|
|
1623
1648
|
/**
|
|
@@ -1662,14 +1687,14 @@ function serializeRequestBody(request, operationArguments, operationSpec, string
|
|
|
1662
1687
|
xml: {
|
|
1663
1688
|
rootName: (_b = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.rootName) !== null && _b !== void 0 ? _b : "",
|
|
1664
1689
|
includeRoot: (_c = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.includeRoot) !== null && _c !== void 0 ? _c : false,
|
|
1665
|
-
xmlCharKey: (_d = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.xmlCharKey) !== null && _d !== void 0 ? _d : XML_CHARKEY
|
|
1666
|
-
}
|
|
1690
|
+
xmlCharKey: (_d = serializerOptions === null || serializerOptions === void 0 ? void 0 : serializerOptions.xml.xmlCharKey) !== null && _d !== void 0 ? _d : XML_CHARKEY,
|
|
1691
|
+
},
|
|
1667
1692
|
};
|
|
1668
1693
|
const xmlCharKey = updatedOptions.xml.xmlCharKey;
|
|
1669
1694
|
if (operationSpec.requestBody && operationSpec.requestBody.mapper) {
|
|
1670
1695
|
request.body = getOperationArgumentValueFromParameter(operationArguments, operationSpec.requestBody);
|
|
1671
1696
|
const bodyMapper = operationSpec.requestBody.mapper;
|
|
1672
|
-
const { required, serializedName, xmlName, xmlElementName, xmlNamespace, xmlNamespacePrefix, nullable } = bodyMapper;
|
|
1697
|
+
const { required, serializedName, xmlName, xmlElementName, xmlNamespace, xmlNamespacePrefix, nullable, } = bodyMapper;
|
|
1673
1698
|
const typeName = bodyMapper.type.name;
|
|
1674
1699
|
try {
|
|
1675
1700
|
if ((request.body !== undefined && request.body !== null) ||
|
|
@@ -1687,7 +1712,7 @@ function serializeRequestBody(request, operationArguments, operationSpec, string
|
|
|
1687
1712
|
else if (!isStream) {
|
|
1688
1713
|
request.body = stringifyXML(value, {
|
|
1689
1714
|
rootName: xmlName || serializedName,
|
|
1690
|
-
xmlCharKey
|
|
1715
|
+
xmlCharKey,
|
|
1691
1716
|
});
|
|
1692
1717
|
}
|
|
1693
1718
|
}
|
|
@@ -1755,12 +1780,12 @@ function createClientPipeline(options = {}) {
|
|
|
1755
1780
|
if (options.credentialOptions) {
|
|
1756
1781
|
pipeline.addPolicy(coreRestPipeline.bearerTokenAuthenticationPolicy({
|
|
1757
1782
|
credential: options.credentialOptions.credential,
|
|
1758
|
-
scopes: options.credentialOptions.credentialScopes
|
|
1783
|
+
scopes: options.credentialOptions.credentialScopes,
|
|
1759
1784
|
}));
|
|
1760
1785
|
}
|
|
1761
1786
|
pipeline.addPolicy(serializationPolicy(options.serializationOptions), { phase: "Serialize" });
|
|
1762
1787
|
pipeline.addPolicy(deserializationPolicy(options.deserializationOptions), {
|
|
1763
|
-
phase: "Deserialize"
|
|
1788
|
+
phase: "Deserialize",
|
|
1764
1789
|
});
|
|
1765
1790
|
return pipeline;
|
|
1766
1791
|
}
|
|
@@ -1804,7 +1829,7 @@ class ServiceClient {
|
|
|
1804
1829
|
// not part of OperationArguments
|
|
1805
1830
|
const url = getRequestUrl(baseUri, operationSpec, operationArguments, this);
|
|
1806
1831
|
const request = coreRestPipeline.createPipelineRequest({
|
|
1807
|
-
url
|
|
1832
|
+
url,
|
|
1808
1833
|
});
|
|
1809
1834
|
request.method = operationSpec.httpMethod;
|
|
1810
1835
|
const operationInfo = getOperationRequestInfo(request);
|
|
@@ -1886,10 +1911,78 @@ function getCredentialScopes(options) {
|
|
|
1886
1911
|
return undefined;
|
|
1887
1912
|
}
|
|
1888
1913
|
|
|
1914
|
+
// Copyright (c) Microsoft Corporation.
|
|
1915
|
+
const defaultLogger = logger.createClientLogger("authorizeRequestOnClaimChallenge");
|
|
1916
|
+
/**
|
|
1917
|
+
* Converts: `Bearer a="b", c="d", Bearer d="e", f="g"`.
|
|
1918
|
+
* Into: `[ { a: 'b', c: 'd' }, { d: 'e', f: 'g' } ]`.
|
|
1919
|
+
*
|
|
1920
|
+
* @internal
|
|
1921
|
+
*/
|
|
1922
|
+
function parseCAEChallenge(challenges) {
|
|
1923
|
+
const bearerChallenges = `, ${challenges.trim()}`.split(", Bearer ").filter((x) => x);
|
|
1924
|
+
return bearerChallenges.map((challenge) => {
|
|
1925
|
+
const challengeParts = `${challenge.trim()}, `.split('", ').filter((x) => x);
|
|
1926
|
+
const keyValuePairs = challengeParts.map((keyValue) => (([key, value]) => ({ [key]: value }))(keyValue.trim().split('="')));
|
|
1927
|
+
// Key-value pairs to plain object:
|
|
1928
|
+
return keyValuePairs.reduce((a, b) => (Object.assign(Object.assign({}, a), b)), {});
|
|
1929
|
+
});
|
|
1930
|
+
}
|
|
1931
|
+
/**
|
|
1932
|
+
* This function can be used as a callback for the `bearerTokenAuthenticationPolicy` of `@azure/core-rest-pipeline`, to support CAE challenges:
|
|
1933
|
+
* [Continuous Access Evaluation](https://docs.microsoft.com/azure/active-directory/conditional-access/concept-continuous-access-evaluation).
|
|
1934
|
+
*
|
|
1935
|
+
* Call the `bearerTokenAuthenticationPolicy` with the following options:
|
|
1936
|
+
*
|
|
1937
|
+
* ```ts
|
|
1938
|
+
* import { bearerTokenAuthenticationPolicy } from "@azure/core-rest-pipeline";
|
|
1939
|
+
* import { authorizeRequestOnClaimChallenge } from "@azure/core-client";
|
|
1940
|
+
*
|
|
1941
|
+
* const bearerTokenAuthenticationPolicy = bearerTokenAuthenticationPolicy({
|
|
1942
|
+
* authorizeRequestOnChallenge: authorizeRequestOnClaimChallenge
|
|
1943
|
+
* });
|
|
1944
|
+
* ```
|
|
1945
|
+
*
|
|
1946
|
+
* Once provided, the `bearerTokenAuthenticationPolicy` policy will internally handle Continuous Access Evaluation (CAE) challenges.
|
|
1947
|
+
* When it can't complete a challenge it will return the 401 (unauthorized) response from ARM.
|
|
1948
|
+
*
|
|
1949
|
+
* Example challenge with claims:
|
|
1950
|
+
*
|
|
1951
|
+
* ```
|
|
1952
|
+
* Bearer authorization_uri="https://login.windows-ppe.net/", error="invalid_token",
|
|
1953
|
+
* error_description="User session has been revoked",
|
|
1954
|
+
* claims="eyJhY2Nlc3NfdG9rZW4iOnsibmJmIjp7ImVzc2VudGlhbCI6dHJ1ZSwgInZhbHVlIjoiMTYwMzc0MjgwMCJ9fX0="
|
|
1955
|
+
* ```
|
|
1956
|
+
*/
|
|
1957
|
+
async function authorizeRequestOnClaimChallenge(onChallengeOptions) {
|
|
1958
|
+
const { scopes, response } = onChallengeOptions;
|
|
1959
|
+
const logger = onChallengeOptions.logger || defaultLogger;
|
|
1960
|
+
const challenge = response.headers.get("WWW-Authenticate");
|
|
1961
|
+
if (!challenge) {
|
|
1962
|
+
logger.info(`The WWW-Authenticate header was missing. Failed to perform the Continuous Access Evaluation authentication flow.`);
|
|
1963
|
+
return false;
|
|
1964
|
+
}
|
|
1965
|
+
const challenges = parseCAEChallenge(challenge) || [];
|
|
1966
|
+
const parsedChallenge = challenges.find((x) => x.claims);
|
|
1967
|
+
if (!parsedChallenge) {
|
|
1968
|
+
logger.info(`The WWW-Authenticate header was missing the necessary "claims" to perform the Continuous Access Evaluation authentication flow.`);
|
|
1969
|
+
return false;
|
|
1970
|
+
}
|
|
1971
|
+
const accessToken = await onChallengeOptions.getAccessToken(parsedChallenge.scope ? [parsedChallenge.scope] : scopes, {
|
|
1972
|
+
claims: decodeStringToString(parsedChallenge.claims),
|
|
1973
|
+
});
|
|
1974
|
+
if (!accessToken) {
|
|
1975
|
+
return false;
|
|
1976
|
+
}
|
|
1977
|
+
onChallengeOptions.request.headers.set("Authorization", `Bearer ${accessToken.token}`);
|
|
1978
|
+
return true;
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1889
1981
|
exports.MapperTypeNames = MapperTypeNames;
|
|
1890
1982
|
exports.ServiceClient = ServiceClient;
|
|
1891
1983
|
exports.XML_ATTRKEY = XML_ATTRKEY;
|
|
1892
1984
|
exports.XML_CHARKEY = XML_CHARKEY;
|
|
1985
|
+
exports.authorizeRequestOnClaimChallenge = authorizeRequestOnClaimChallenge;
|
|
1893
1986
|
exports.createClientPipeline = createClientPipeline;
|
|
1894
1987
|
exports.createSerializer = createSerializer;
|
|
1895
1988
|
exports.deserializationPolicy = deserializationPolicy;
|