UNPKG

@sap-cloud-sdk/connectivity

Version:

SAP Cloud SDK for JavaScript connectivity

282 lines • 11.9 kB
"use strict"; 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