UNPKG

@attivio/fetch-utils

Version:

Wrapper around the fetch() API to use when communicating with the Attivio REST APIs authenticated with SAML.

170 lines (150 loc) 7.18 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Utility class to handle fetch requests for the Attivio REST * APIs. Attempts to handle SAML-related redirects to log into * the identity provider by redirecting to the special "login" * page served by the Attivio servlet, which redirects to the * URI the browser is currently showing after successfully * logging in (if the user is already logged into the * identity provider from the client application, the logging * in should happen without the need for the user's intervention. */ var FetchUtils = function () { function FetchUtils() { _classCallCheck(this, FetchUtils); } _createClass(FetchUtils, null, [{ key: 'fetch', /** * Make a fetch call to the REST API. Ensure that all requests * are handled in a similar way. * * @param baseUri the base part of the URI to reach the * Attivio server (this should end in a /) * @param endpointUri the endpoint-specific part of the URI * to contact (appended to the baseUri) * @param payload an object to send in the request body, * or null if not applicable * @param callback a function to call when the request * completes. If the request is successful, * the response parameter is set to the JSON * response, otherwise the error parameter * is set to a reason for the failure. * @param method the HTTP method to use (e.g. GET or PUT); * should be an uppercase string (see the * HttpMethod type) * @param defaultErrorMessage the default error message to return if * the fetch call doesn't provide one of its own. */ value: function (_fetch) { function fetch(_x, _x2, _x3, _x4, _x5, _x6) { return _fetch.apply(this, arguments); } fetch.toString = function () { return _fetch.toString(); }; return fetch; }(function (baseUri, endpointUri, payload, callback, method, defaultErrorMessage) { var uri = '' + baseUri + endpointUri; var headers = new Headers({ Accept: 'application/json', 'Content-Type': 'application/json' }); var body = payload ? JSON.stringify(payload) : null; var params = { method: method, headers: headers, body: body, mode: 'cors', redirect: 'follow', credentials: 'include' }; var fetchRequest = new Request(uri, params); fetch(fetchRequest).then(function (response) { if (response.ok) { var contentType = response.headers.get('content-type'); if (!contentType || contentType.indexOf('text/html') === -1) { response.json().then(function (jsonResponse) { callback(jsonResponse, null); }).catch(function (error) { // Catch errors from converting the response's JSON callback(null, FetchUtils.getErrorMessage(error, defaultErrorMessage)); }); } else { // If the response content-type is HTML then reload the page because user's session likely timed out. // SAML tries to redirect but we can't deal with that in Ajax. FetchUtils.forward(baseUri); } } else { // The request came back other than a 200-type response code // There should be JSON describing it... response.json().then(function (searchException) { var exceptionMessage = searchException.message ? searchException.message : ''; var exceptionCode = searchException.errorCode ? ' (' + searchException.errorCode + ')' : ''; var finalExceptionMessage = defaultErrorMessage + ' ' + exceptionMessage + ' ' + exceptionCode + ' '; callback(null, finalExceptionMessage); }).catch(function (badJsonError) { callback(null, FetchUtils.getErrorMessage(badJsonError, defaultErrorMessage)); }); } }, function () { // Catch network-type errors from the main fetch() call and reload the page. FetchUtils.forward(baseUri); }).catch(function (error) { // Catch exceptions from the main "then" function callback(null, FetchUtils.getErrorMessage(error, defaultErrorMessage)); }); }) /** * Called to forward failed fetch calls through the special login * endpoint to force a re-up of the SAML authentication. * * @param baseUri the base URI for the Attivio server */ }, { key: 'forward', value: function forward(baseUri) { // First try to open a window behind ourselves that will trigger the SAML log in and close itself var closerUrl = baseUri + 'closer.html'; var newWindow = window.open(closerUrl, 'attivio_validation', 'alwaysLowered=1,dependent=1'); if (newWindow) { // We were able to open the new window... it'll close itself once it manages to authenticate newWindow.blur(); window.focus(); } else { // The "pop-up" was blocked, so try the potentially more in-your-face way using the login endpoint var currentUri = window.location.href; var encodedUri = encodeURIComponent(currentUri); var newUri = baseUri + 'rest/login?uri=' + encodedUri; window.location = newUri; } } /** * Get an error message to display to the user. * * @param error the error received * @param defaultErrorMessage a default message to show if the actual error * doesn't say anything * @return a string representing the error that occurred, * passed to the fetch() callback */ }, { key: 'getErrorMessage', value: function getErrorMessage(error, defaultErrorMessage) { var message = void 0; if (error && error.message) { message = error.message; } else { message = defaultErrorMessage; } return message; } }]); return FetchUtils; }(); exports.default = FetchUtils;