handles session timeouts in modals (#1092)
This commit is contained in:
@@ -57,12 +57,9 @@ export default class KimaiAjaxModalForm extends KimaiClickHandlerReducedInTableR
|
||||
|
||||
if (errorHandler === undefined) {
|
||||
errorHandler = function(xhr, err) {
|
||||
if (xhr.status !== undefined && xhr.status === 403) {
|
||||
const alert = self.getContainer().getPlugin('alert');
|
||||
alert.error(xhr.statusText);
|
||||
return;
|
||||
if (xhr.status === undefined || xhr.status !== 403) {
|
||||
window.location = url;
|
||||
}
|
||||
window.location = url;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ import KimaiPlugin from '../KimaiPlugin';
|
||||
export default class KimaiThemeInitializer extends KimaiPlugin {
|
||||
|
||||
init() {
|
||||
this.registerGlobalAjaxErrorHandler();
|
||||
this.registerAutomaticAlertRemove('div.alert-success', 5000);
|
||||
|
||||
// activate the dropdown functionality
|
||||
jQuery('.dropdown-toggle').dropdown();
|
||||
// activate the tooltip functionality
|
||||
@@ -25,6 +25,27 @@ export default class KimaiThemeInitializer extends KimaiPlugin {
|
||||
this.getContainer().getPlugin('form').activateForm('.content-wrapper form', 'body');
|
||||
}
|
||||
|
||||
/**
|
||||
* redirect access denied / session timeouts to login page
|
||||
*/
|
||||
registerGlobalAjaxErrorHandler() {
|
||||
const loginUrl = this.getContainer().getConfiguration().get('login');
|
||||
const alert = this.getContainer().getPlugin('alert');
|
||||
const translation = this.getContainer().getTranslation().get('login.required');
|
||||
jQuery(document).ajaxError(function(event, jqxhr, settings, thrownError) {
|
||||
if (jqxhr.status !== undefined && jqxhr.status === 403) {
|
||||
const loginRequired = jqxhr.getResponseHeader('login-required');
|
||||
if (loginRequired !== null) {
|
||||
alert.question(translation, function (result) {
|
||||
if (result === true) {
|
||||
window.location.replace(loginUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* auto hide success messages, as they are just meant as user feedback and not as a permanent information
|
||||
*
|
||||
|
||||
@@ -37,7 +37,7 @@ nelmio_api_doc:
|
||||
info:
|
||||
title: Kimai 2 - API Docs
|
||||
description: |
|
||||
REST API for the Kimai 2 time-tracking software. Read more about its usage in the [API documentation](https://www.kimai.org/documentation/rest-api.html) and then download a [Swagger file](doc.json) for import e.g. in Postman.
|
||||
JSON API for the Kimai 2 time-tracking software. Read more about its usage in the [API documentation](https://www.kimai.org/documentation/rest-api.html) and then download a [Swagger file](doc.json) for import e.g. in Postman.
|
||||
Be aware: it is not yet considered stable and BC breaks might happen, but we try to avoid them.
|
||||
version: 0.3
|
||||
securityDefinitions:
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
||||
"build/runtime.f02eb7c9.js",
|
||||
"build/0.2372f97a.js",
|
||||
"build/1.eec3372c.js",
|
||||
"build/app.608dd464.js"
|
||||
"build/app.21c06505.js"
|
||||
],
|
||||
"css": [
|
||||
"build/app.af6cd671.css"
|
||||
@@ -35,7 +35,7 @@
|
||||
"build/runtime.f02eb7c9.js": "sha384-xNNrNinl64G3nCUrIskgSjU0mUXXCB9lj6XCSInBTwxSKXk8uTMafnLHtdWdIGtd",
|
||||
"build/0.2372f97a.js": "sha384-+My37x5S4cen1I4LYgCVg4Qaa+y8vmPzhpDNLPEoEuH5uBtdwYx6ACOxm23nW0UP",
|
||||
"build/1.eec3372c.js": "sha384-7UVWcP6Hefp2k/CrtGSITKXx4dSZqtvpAiU8WX7dClETkzMewrUjoCRtVXQ5j3KI",
|
||||
"build/app.608dd464.js": "sha384-dnyOfN3SyZEO87bNKmrrsicXn1usVTQcqmw1pe7cLtr+zO50b09tsIPsUkfAqJJv",
|
||||
"build/app.21c06505.js": "sha384-e7hmqWhNBpDXkCu8f0ASmtcnqxenbVJ+XqAYlh0+m8MZGM8FHUwHYmbWep38WKrf",
|
||||
"build/app.af6cd671.css": "sha384-N8TrohuaS6twRAMAhyy+5o3qV69cT6KGgsvKiLmHMCmRIV3zssFoM14+pO92w+JL",
|
||||
"build/2.ad3e2792.js": "sha384-1aYWOOt09EZyaAlTHQzsuBKU1b+iDuMEen4m8lrRIm7awHvYkP82CWAowcKZ+XuW",
|
||||
"build/chart.a0ca6955.js": "sha384-I57c9DtU3AOG2kzKqIZkIu0hi1aGYHRZ5QG4LKC9+9slzJnAMttPGXoL2cQG3m6y",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"build/1.eec3372c.js": "build/1.eec3372c.js",
|
||||
"build/2.ad3e2792.js": "build/2.ad3e2792.js",
|
||||
"build/app.css": "build/app.af6cd671.css",
|
||||
"build/app.js": "build/app.608dd464.js",
|
||||
"build/app.js": "build/app.21c06505.js",
|
||||
"build/calendar.css": "build/calendar.8bb56227.css",
|
||||
"build/calendar.js": "build/calendar.340fd7f1.js",
|
||||
"build/chart.js": "build/chart.a0ca6955.js",
|
||||
|
||||
44
src/EventSubscriber/AjaxAuthenticationSubscriber.php
Normal file
44
src/EventSubscriber/AjaxAuthenticationSubscriber.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\EventSubscriber;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationExpiredException;
|
||||
|
||||
class AjaxAuthenticationSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
KernelEvents::EXCEPTION => ['onCoreException', 1]
|
||||
];
|
||||
}
|
||||
|
||||
public function onCoreException(ExceptionEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
|
||||
if ($request->isXmlHttpRequest()) {
|
||||
$exception = $event->getException();
|
||||
if ($exception instanceof AuthenticationExpiredException) {
|
||||
$event->setResponse(new Response('Session expired', 403, ['Login-Required' => true]));
|
||||
} elseif ($exception instanceof AuthenticationException) {
|
||||
$event->setResponse(new Response('Authentication problem', 403, ['Login-Required' => true]));
|
||||
} elseif ($exception instanceof AccessDeniedException) {
|
||||
$event->setResponse(new Response('Access denied', 403, ['Login-Required' => true]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ class TimesheetToolbarForm extends AbstractToolbarForm
|
||||
{
|
||||
$this->addSearchTermInputField($builder);
|
||||
if ($options['include_user']) {
|
||||
$this->addUserChoice($builder);
|
||||
$this->addUsersChoice($builder);
|
||||
}
|
||||
$this->addDateRangeChoice($builder);
|
||||
$this->addCustomerChoice($builder);
|
||||
|
||||
@@ -201,6 +201,7 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var loader = new KimaiWebLoader(
|
||||
{
|
||||
login: '{{ path('fos_user_security_login') }}',
|
||||
locale: '{{ app.request.locale }}',
|
||||
twentyFourHours: {{ 'true'|hour24('false') }},
|
||||
autoReloadDatatable: {% if theme_config('auto_reload_datatable') %}true{% else %}false{% endif %},
|
||||
@@ -228,7 +229,8 @@
|
||||
'action.delete.success': '{{ 'action.delete.success'|trans({}, 'flashmessages') }}',
|
||||
'action.delete.error': '{{ 'action.delete.error'|trans({}, 'flashmessages') }}',
|
||||
'confirm.delete': '{{ 'confirm.delete' |trans }}',
|
||||
'delete': '{{ 'action.delete' |trans }}'
|
||||
'delete': '{{ 'action.delete' |trans }}',
|
||||
'login.required': '{{ 'login_required'|trans }}'
|
||||
}
|
||||
);
|
||||
window.kimai = loader.getKimai();
|
||||
|
||||
@@ -67,7 +67,7 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
|
||||
$form = $client->getCrawler()->filter('form.header-search')->form();
|
||||
$client->submit($form, [
|
||||
'state' => 1,
|
||||
'user' => $user->getId(),
|
||||
'users' => [$user->getId()],
|
||||
'pageSize' => 25,
|
||||
'daterange' => $dateRange,
|
||||
'customer' => null,
|
||||
|
||||
@@ -84,6 +84,10 @@
|
||||
<source>label.api_token_repeat</source>
|
||||
<target>API Passwort wiederholen</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="login_required">
|
||||
<source>login_required</source>
|
||||
<target>Fehlende Berechtigung. Zur Anmeldung wechseln?</target>
|
||||
</trans-unit>
|
||||
|
||||
<!--
|
||||
Menu / Navbar items
|
||||
|
||||
@@ -84,6 +84,10 @@
|
||||
<source>label.api_token_repeat</source>
|
||||
<target>Repeat API password</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="login_required">
|
||||
<source>login_required</source>
|
||||
<target>Missing permission. Redirect to login?</target>
|
||||
</trans-unit>
|
||||
|
||||
<!--
|
||||
Menu / Navbar items
|
||||
|
||||
Reference in New Issue
Block a user