@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
JavaScript
;
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;