mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-10-07 01:52:20 -04:00
* fix(auth): return 401 JSON for AJAX requests on session timeout (#4696) IsLoggedIn previously threw RedirectException('login') for every request type. For XHR calls the browser transparently followed the 302 and fetched the login page's HTML where JSON was expected, so the table silently rendered empty and the failure looked like a broken sort. - Server: IsLoggedIn::before() now returns a JSON 401 response when the request is an AJAX call, keeping the redirect behavior for normal navigations. - Client: a global $(document).ajaxError handler in the authenticated layout redirects to the login URL on a 401 response. * fix(auth): run isLoggedIn before csrf for expired sessions (#4696) An expired-session AJAX POST with an invalid CSRF token was hitting the globally-configured csrf filter first, which throws a CSRF exception before isLoggedIn can return its 401. Reorder the global before-filters so the authentication check runs before CSRF validation; CSRF protection is fully retained for authenticated requests. --------- Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
95 lines
2.7 KiB
PHP
95 lines
2.7 KiB
PHP
<?php
|
|
/**
|
|
* @var array $config
|
|
*/
|
|
?>
|
|
|
|
<script type="text/javascript">
|
|
// Live clock
|
|
const clock_tick = function clock_tick() {
|
|
setInterval('update_clock();', 1000);
|
|
}
|
|
|
|
// Start the clock immediately
|
|
clock_tick();
|
|
|
|
const update_clock = function update_clock() {
|
|
document.getElementById('liveclock').innerHTML = moment().format("<?= dateformat_momentjs($config['dateformat'] . ' ' . $config['timeformat']) ?>");
|
|
}
|
|
|
|
const notify = $.notify;
|
|
|
|
$.notify = function(content, options) {
|
|
const message = typeof content === "object" ? content.message : content;
|
|
const sanitizedMessage = DOMPurify.sanitize(message, { ALLOWED_TAGS: [], ALLOWED_ATTR: [] });
|
|
return notify(sanitizedMessage, options);
|
|
};
|
|
|
|
$.notifyDefaults({
|
|
placement: {
|
|
align: "<?= esc($config['notify_horizontal_position'], 'js') ?>",
|
|
from: "<?= esc($config['notify_vertical_position'], 'js') ?>"
|
|
}
|
|
});
|
|
|
|
const csrf_token = function() {
|
|
return "<?= esc(csrf_hash(), 'js') ?>";
|
|
};
|
|
|
|
const csrf_form_base = function() {
|
|
return {
|
|
<?= esc(config('Security')->tokenName, 'js') ?>: function() {
|
|
return csrf_token()
|
|
}
|
|
}
|
|
};
|
|
|
|
const setup_csrf_token = function() {
|
|
$('input[name="<?= esc(config('Security')->tokenName, 'js') ?>"]').val(csrf_token());
|
|
};
|
|
|
|
const ajax = $.ajax;
|
|
|
|
$.ajax = function() {
|
|
let args = arguments[0];
|
|
if (args['type'] && args['type'].toLowerCase() == 'post' && csrf_token()) {
|
|
if (typeof args['data'] === 'string') {
|
|
args['data'] += '&' + $.param(csrf_form_base());
|
|
} else {
|
|
args['data'] = $.extend(args['data'], csrf_form_base());
|
|
}
|
|
}
|
|
|
|
return ajax.apply(this, arguments);
|
|
};
|
|
|
|
$(document).ajaxComplete(setup_csrf_token);
|
|
$(document).ajaxError(function(event, jqXHR, settings) {
|
|
if (jqXHR.status === 401) {
|
|
window.location.href = '<?= site_url('login') ?>';
|
|
}
|
|
});
|
|
$(document).ready(function() {
|
|
$("#logout").click(function(event) {
|
|
event.preventDefault();
|
|
$.ajax({
|
|
url: "<?= site_url('home/logout'); ?>",
|
|
data: {
|
|
"<?= esc(config('Security')->tokenName, 'js'); ?>": csrf_token()
|
|
},
|
|
success: function() {
|
|
window.location.href = '<?= site_url(); ?>';
|
|
},
|
|
method: "POST"
|
|
});
|
|
});
|
|
});
|
|
|
|
const submit = $.fn.submit;
|
|
|
|
$.fn.submit = function() {
|
|
setup_csrf_token();
|
|
submit.apply(this, arguments);
|
|
};
|
|
</script>
|