Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions src/Glpi/Kernel/Listener/ExceptionListener/AccessErrorListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
use Glpi\Application\View\TemplateRenderer;
use Glpi\Exception\AuthenticationFailedException;
use Glpi\Exception\Http\AccessDeniedHttpException;
use Glpi\Exception\Http\HttpException;
use Glpi\Exception\SessionExpiredException;
use Glpi\Http\RedirectResponse;
use Session;
Expand All @@ -62,12 +63,6 @@ public function onKernelException(ExceptionEvent $event): void
}

$request = $event->getRequest();

if ($request->isXmlHttpRequest() || $request->getPreferredFormat() !== 'html') {
// Do not redirect AJAX requests nor requests that expect the response to be something else than HTML.
return;
}

$throwable = $event->getThrowable();

$response = null;
Expand All @@ -79,18 +74,37 @@ public function onKernelException(ExceptionEvent $event): void
->getBoolean('_redirected_from_profile_selector')
;

// Handle SessionExpiredException BEFORE checking if request is AJAX
// This ensures that expired sessions return proper HTTP 401 response for AJAX requests
if ($throwable instanceof SessionExpiredException) {
Session::destroy(); // destroy the session to prevent pesistence of unexpected data

$response = new RedirectResponse(
sprintf(
'%s/?redirect=%s&error=3',
$request->getBasePath(),
\rawurlencode($request->getPathInfo() . '?' . $request->getQueryString())
)
);
} elseif (
$throwable instanceof AccessDeniedHttpException
if ($request->isXmlHttpRequest() || $request->getPreferredFormat() !== 'html') {
// For AJAX/JSON requests, convert the error into a HttpException
$http_exception = new HttpException(401, 'Session expired.');
$http_exception->setMessageToDisplay(__('Your session has expired. Please log in again.'));
throw $http_exception;
} else {
// For HTML requests, redirect to login page (existing behavior)
$response = new RedirectResponse(
sprintf(
'%s/?redirect=%s&error=3',
$request->getBasePath(),
\rawurlencode($request->getPathInfo() . '?' . $request->getQueryString())
)
);
}
}

// Skip AJAX requests for OTHER exceptions (not SessionExpiredException)
if ($response === null && ($request->isXmlHttpRequest() || $request->getPreferredFormat() !== 'html')) {
// Do not redirect AJAX requests nor requests that expect the response to be something else than HTML.
return;
}

if (
$response === null
&& $throwable instanceof AccessDeniedHttpException
&& $redirect_to_home_on_error
) {
$request = $event->getRequest();
Expand All @@ -100,7 +114,9 @@ public function onKernelException(ExceptionEvent $event): void
$request->getBasePath()
)
);
} elseif ($throwable instanceof AuthenticationFailedException) {
}

if ($response === null && $throwable instanceof AuthenticationFailedException) {
$login_url = sprintf(
'%s/front/logout.php?noAUTO=1',
$request->getBasePath()
Expand Down