diff --git a/htdocs/js/loris-scripts.js b/htdocs/js/loris-scripts.js index d07ae39f48..f49b6e74f9 100644 --- a/htdocs/js/loris-scripts.js +++ b/htdocs/js/loris-scripts.js @@ -1,5 +1,70 @@ /* eslint new-cap: ["error", {capIsNewExceptions: ["DynamicTable", "FileUpload"]}]*/ +/** + * Display the login modal when a request returns a 401 response. + */ +function handleUnauthorized() { + if (!window.$ || !window.loris) { + return; + } + + if (!$('#login-modal').length) { + return; + } + + if ($('#login-modal').hasClass('in')) { + $('#login-modal-error').show(); + return; + } + + $('#login-modal').modal('show'); + $('#modal-login') + .off('click.lorisFetch') + .on('click.lorisFetch', function(e) { + e.preventDefault(); + let data = { + username: $('#modal-username').val(), + password: $('#modal-password').val(), + login: 'Login', + }; + + window.lorisFetch(window.loris.BaseURL, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + }, + body: new URLSearchParams(data), + }) + .then((response) => { + if (!response.ok) { + throw new Error('request_failed'); + } + $('#login-modal-error').hide(); + $('#login-modal').modal('hide'); + }) + .catch(() => { + $('#login-modal-error').show(); + }); + }); +} + +if (!window.lorisFetch) { + window.lorisFetch = function(input, init) { + const options = Object.assign( + { + credentials: 'same-origin', + }, + init || {} + ); + return fetch(input, options).then((response) => { + if (response.status === 401) { + handleUnauthorized(); + } + return response; + }); + }; +} + $(document).ready(function() { $('#menu-toggle').click(function(e) { e.preventDefault(); @@ -8,30 +73,3 @@ $(document).ready(function() { $('.dynamictable').DynamicTable(); $('.fileUpload').FileUpload(); }); - -$(document).ajaxError(function(event, jqxhr, settings, thrownError) { - if (jqxhr.status === 401) { - if ($('#login-modal').hasClass('in')) { - $('#login-modal-error').show(); - } else { - $('#login-modal').modal('show'); - $('#modal-login').click(function(e) { - e.preventDefault(); - let data = { - username: $('#modal-username').val(), - password: $('#modal-password').val(), - login: 'Login', - }; - $.ajax({ - type: 'post', - url: loris.BaseURL, - data: data, - success: function() { - $('#login-modal-error').hide(); - $('#login-modal').modal('hide'); - }, - }); - }); - } - } -}); diff --git a/jslib/lorisFetch.js b/jslib/lorisFetch.js new file mode 100644 index 0000000000..1aba03792c --- /dev/null +++ b/jslib/lorisFetch.js @@ -0,0 +1,81 @@ +/** + * Display the login modal when a request returns a 401 response. + */ +function handleUnauthorized() { + if (typeof window === 'undefined') { + return; + } + if (!window.$ || !window.loris) { + return; + } + + const $ = window.$; + if (!$('#login-modal').length) { + return; + } + + if ($('#login-modal').hasClass('in')) { + $('#login-modal-error').show(); + return; + } + + $('#login-modal').modal('show'); + $('#modal-login') + .off('click.lorisFetch') + .on('click.lorisFetch', function(e) { + e.preventDefault(); + let data = { + username: $('#modal-username').val(), + password: $('#modal-password').val(), + login: 'Login', + }; + + fetch(window.loris.BaseURL, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + }, + body: new URLSearchParams(data), + credentials: 'same-origin', + }) + .then((response) => { + if (!response.ok) { + throw new Error('request_failed'); + } + $('#login-modal-error').hide(); + $('#login-modal').modal('hide'); + }) + .catch(() => { + $('#login-modal-error').show(); + }); + }); +} + +/** + * Wrapper around fetch that keeps credentials and handles 401s. + * + * @param {*} input + * @param {object=} init + * @return {Promise} + */ +function lorisFetch(input, init) { + const options = Object.assign( + { + credentials: 'same-origin', + }, + init || {} + ); + + return fetch(input, options).then((response) => { + if (response.status === 401) { + handleUnauthorized(); + } + return response; + }); +} + +if (typeof window !== 'undefined') { + window.lorisFetch = lorisFetch; +} + +export default lorisFetch;