@sap-cloud-sdk/connectivity
Version:
SAP Cloud SDK for JavaScript connectivity
282 lines • 11.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.sanitizeDestination = sanitizeDestination;
exports.parseDestination = parseDestination;
exports.getAdditionalHeadersAndQueryParameters = getAdditionalHeadersAndQueryParameters;
exports.getAdditionalHeaders = getAdditionalHeaders;
exports.getAdditionalQueryParameters = getAdditionalQueryParameters;
exports.getDestinationConfig = getDestinationConfig;
exports.toDestinationNameUrl = toDestinationNameUrl;
exports.parseCertificate = parseCertificate;
exports.isDestinationConfiguration = isDestinationConfiguration;
exports.isDestinationJson = isDestinationJson;
exports.noDestinationErrorMessage = noDestinationErrorMessage;
const destination_accessor_types_1 = require("./destination-accessor-types");
/**
* Takes an existing or a parsed destination and returns an SDK compatible destination object.
* @param destination - An object that adheres to the {@link Destination} interface.
* @returns An SDK compatible destination object.
*/
function sanitizeDestination(destination) {
let parsedDestination = parseAuthTokens(destination);
parsedDestination = parseCertificates(parsedDestination);
parsedDestination = setDefaultAuthenticationFallback(parsedDestination);
parsedDestination = setTrustAll(parsedDestination);
parsedDestination = setForwardAuthToken(parsedDestination);
parsedDestination = setOriginalProperties(parsedDestination);
return parsedDestination;
}
/**
* Takes a JSON object returned by any of the calls to the destination service and returns an SDK compatible destination object.
* This function only accepts destination configurations of type 'HTTP' and will error if no 'URL' is given.
* @param destinationJson - A JSON object returned by the destination service.
* @returns An SDK compatible destination object.
* @internal
*/
function parseDestination(destinationJson) {
const destinationConfig = getDestinationConfig(destinationJson);
const destination = Object.entries(destinationConfig).reduce((dest, [originalKey, value]) => {
if (originalKey in configMapping) {
dest[configMapping[originalKey]] = value;
}
return dest;
}, {
originalProperties: destinationJson,
authTokens: destinationJson['authTokens'] || [],
certificates: destinationJson['certificates'] || []
});
const additionalHeadersAndQueryParameters = getAdditionalHeadersAndQueryParameters(destinationConfig);
return sanitizeDestination({
...destination,
...additionalHeadersAndQueryParameters
});
}
/**
* Get either additional headers or query parameters from a destination, depending on the given prefix.
* @param destinationConfig - Original destination config that could include additional headers or query parameters.
* @param originalKeyPrefix - This is what the additional header and query keys start with, when specified in the original destination config.
* @returns An object with either the headers or query parameters and their values, depending on the `originalKeyPrefix`.
*/
function getAdditionalProperties(destinationConfig, originalKeyPrefix) {
const relevantConfigEntries = Object.entries(destinationConfig).filter(([key]) => key.startsWith(originalKeyPrefix));
return relevantConfigEntries.reduce((additionalProperties, [originalKey, value]) => {
const headerKey = originalKey.replace(originalKeyPrefix, '');
additionalProperties[headerKey] = value;
return additionalProperties;
}, {});
}
/**
* @internal
* Get additional headers and/or query parameters from a destination.
* Destinations can specify additional headers and/or query parameters, that should be added to every request against the given destination.
* They are specified in the following format:
* `URL.headers.<header-name>` or `URL.queries.<query-parameter-name>`
* @param destinationConfig - Original destination config that could include additional headers or query parameters.
* @returns An object with either the headers or query parameters and their values, depending on the `originalKeyPrefix`.
*/
function getAdditionalHeadersAndQueryParameters(destinationConfig) {
const additionalProperties = {};
const additionalHeaders = getAdditionalHeaders(destinationConfig).headers;
if (additionalHeaders && Object.keys(additionalHeaders).length) {
additionalProperties['headers'] = additionalHeaders;
}
const additionalQueryParameters = getAdditionalQueryParameters(destinationConfig).queryParameters;
if (additionalQueryParameters &&
Object.keys(additionalQueryParameters).length) {
additionalProperties['queryParameters'] = additionalQueryParameters;
}
return additionalProperties;
}
/**
* @internal
* Get additional headers from a destination.
* Destinations can specify additional headers, that should be added to every request against the given destination.
* They are specified in the following format:
* `URL.headers.<header-name>`
* @param destinationConfig - Original destination config that could include additional headers.
* @returns An object with either the headers or query parameters and their values, depending on the `originalKeyPrefix`.
*/
function getAdditionalHeaders(destinationConfig) {
const additionalHeaders = getAdditionalProperties(destinationConfig, 'URL.headers.');
const additionalProperties = {};
if (Object.keys(additionalHeaders).length) {
additionalProperties['headers'] = additionalHeaders;
}
return additionalProperties;
}
/**
* @internal
* Get additional query parameters from a destination.
* Destinations can specify additional query parameters, that should be added to every request against the given destination.
* They are specified in the following format:
* `URL.queries.<query-parameter-name>`
* @param destinationConfig - Original destination config that could include additional headers or query parameters.
* @returns An object with either the headers or query parameters and their values, depending on the `originalKeyPrefix`.
*/
function getAdditionalQueryParameters(destinationConfig) {
const additionalQueryParameters = getAdditionalProperties(destinationConfig, 'URL.queries.');
const additionalProperties = {};
if (Object.keys(additionalQueryParameters).length) {
additionalProperties['queryParameters'] = additionalQueryParameters;
}
return additionalProperties;
}
/**
* @internal
*/
function getDestinationConfig(destinationJson) {
return isDestinationJson(destinationJson)
? destinationJson.destinationConfiguration
: destinationJson;
}
/**
* Transform destination to string containing destination information.
* @param destination - Either destination object or destinationName and Jwt.
* @returns String containing information on the destination.
*/
function toDestinationNameUrl(destination) {
if ((0, destination_accessor_types_1.isDestinationFetchOptions)(destination)) {
return `name: ${destination.destinationName}`;
}
const text = ['name', 'url']
.filter(key => destination[key])
.map(key => `${key}: ${destination[key]}`);
return text.length > 0
? text.join(',')
: "Destination does not have a 'name' or 'url' property.";
}
function setOriginalProperties(destination) {
const originalProperties = destination.originalProperties
? destination.originalProperties
: destination;
return {
...destination,
originalProperties
};
}
function setDefaultAuthenticationFallback(destination) {
return destination.authentication
? destination
: {
...destination,
authentication: getAuthenticationType(destination)
};
}
/**
* Transforms the upper case properties of the destination service response to lower case.
* @internal
* @param certificate - Response from the certificate endpoint of the destination service.
* @returns The parsed Destination Certificate with lower case properties.
*/
function parseCertificate(certificate) {
return {
name: certificate.Name || certificate.name,
content: certificate.Content || certificate.content,
type: certificate.Type || certificate.type
};
}
function parseCertificates(destination) {
return {
...destination,
certificates: (destination.certificates || []).map(certificate => parseCertificate(certificate))
};
}
function parseAuthToken(authToken) {
return {
type: authToken.type,
value: authToken.value,
expiresIn: authToken.expires_in,
error: 'error' in authToken ? authToken.error : null,
http_header: authToken.http_header
};
}
function parseAuthTokens(destination) {
return {
...destination,
authTokens: (destination.authTokens || []).map(token => parseAuthToken(token))
};
}
function setTrustAll(destination) {
return {
...destination,
isTrustingAllCertificates: parseTrustAll(destination.isTrustingAllCertificates)
};
}
function parseTrustAll(isTrustingAllCertificates) {
if (typeof isTrustingAllCertificates === 'string') {
return isTrustingAllCertificates.toLowerCase() === 'true';
}
return !!isTrustingAllCertificates;
}
function getAuthenticationType(destination) {
return destination.authentication ||
(destination.username && destination.password)
? 'BasicAuthentication'
: 'NoAuthentication';
}
function setForwardAuthToken(destination) {
const forwardAuthToken = destination.originalProperties?.forwardAuthToken ??
destination.originalProperties?.['HTML5.ForwardAuthToken'] ??
destination.forwardAuthToken;
return {
...destination,
forwardAuthToken: forwardAuthToken === 'true' || forwardAuthToken === true
};
}
/* eslint-disable-next-line valid-jsdoc */
/**
* @internal
*/
function isDestinationConfiguration(destination) {
return destination.URL !== undefined;
}
/* eslint-disable-next-line valid-jsdoc */
/**
* @internal
*/
function isDestinationJson(destination) {
return Object.keys(destination).includes('destinationConfiguration');
}
const configMapping = {
URL: 'url',
Name: 'name',
User: 'username',
Password: 'password',
ProxyType: 'proxyType',
'sap-client': 'sapClient',
Authentication: 'authentication',
TrustAll: 'isTrustingAllCertificates',
Type: 'type',
tokenServiceURL: 'tokenServiceUrl',
clientId: 'clientId',
clientSecret: 'clientSecret',
tokenServiceUser: 'tokenServiceUser',
tokenServicePassword: 'tokenServicePassword',
CloudConnectorLocationId: 'cloudConnectorLocationId',
certificates: 'certificates',
KeyStoreLocation: 'keyStoreName',
KeyStorePassword: 'keyStorePassword',
SystemUser: 'systemUser',
/**
* Base64-encoded JSON web key set, containing the signing keys which are used to validate the JWT provided in the X-User-Token header.
*/
'x_user_token.jwks': 'jwks',
/**
* URI of the JSON web key set, containing the signing keys which are used to validate the JWT provided in the X-User-Token header.
*/
'x_user_token.jwks_uri': 'jwksUri',
'HTML5.ForwardAuthToken': 'forwardAuthToken',
/**
* This overwrites `HTML5.ForwardAuthToken`, if both exist (during sanitize).
*/
forwardAuthToken: 'forwardAuthToken'
};
/**
* @internal
*/
function noDestinationErrorMessage(destination) {
return (0, destination_accessor_types_1.isDestinationFetchOptions)(destination)
? `Could not find a destination with name "${destination.destinationName}"! Unable to execute request.`
: 'Could not find a destination to execute request against and no destination name has been provided (this should never happen)!';
}
//# sourceMappingURL=destination.js.map