diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php
index 79bc67dd9..ef8662f91 100644
--- a/application/itopwebpage.class.inc.php
+++ b/application/itopwebpage.class.inc.php
@@ -117,7 +117,13 @@ EOF
myLayout.addPinBtn( "#tPinMenu", "west" );
EOF;
}
+
+ $sJSDisconnectedMessage = json_encode(Dict::S('UI:DisconnectedDlgMessage'));
+ $sJSTitle = json_encode(Dict::S('UI:DisconnectedDlgTitle'));
+ $sJSLoginAgain = json_encode(Dict::S('UI:LoginAgain'));
+ $sJSStayOnThePage = json_encode(Dict::S('UI:StayOnThePage'));
+
$this->m_sInitScript =
<<< EOF
try
@@ -391,6 +397,26 @@ EOF
$('#logOffBtn>ul').popupmenu();
$('.caselog_header').click( function () { $(this).toggleClass('open').next('.caselog_entry').toggle(); });
+
+ $(document).ajaxSend(function(event, jqxhr, options) {
+ jqxhr.setRequestHeader('X-Combodo-Ajax', 'true');
+ });
+ $(document).ajaxError(function(event, jqxhr, options) {
+ if (jqxhr.status == 401)
+ {
+ $('
'+$sJSDisconnectedMessage+'
').dialog({
+ modal:true,
+ title: $sJSTitle,
+ close: function() { $(this).remove(); },
+ minWidth: 400,
+ buttons: [
+ { text: $sJSLoginAgain, click: function() { window.location.href= GetAbsoluteUrlAppRoot()+'pages/UI.php' } },
+ { text: $sJSStayOnThePage, click: function() { $(this).dialog('close'); } }
+ ]
+ });
+ }
+ });
+
EOF
);
$sUserPrefs = appUserPreferences::GetAsJSON();
diff --git a/application/loginwebpage.class.inc.php b/application/loginwebpage.class.inc.php
index 84b4dbb2e..9296b43cb 100644
--- a/application/loginwebpage.class.inc.php
+++ b/application/loginwebpage.class.inc.php
@@ -581,6 +581,13 @@ EOF
{
$sLoginMode = $aAllowedLoginTypes[0]; // First in the list...
}
+ if (array_key_exists('HTTP_X_COMBODO_AJAX', $_SERVER))
+ {
+ // X-Combodo-Ajax is a special header automatically added to all ajax requests
+ // Let's reply that we're currently logged-out
+ header('HTTP/1.0 401 Unauthorized');
+ exit;
+ }
if (($iOnExit == self::EXIT_HTTP_401) || ($sLoginMode == 'basic'))
{
header('WWW-Authenticate: Basic realm="'.Dict::Format('UI:iTopVersion:Short', ITOP_VERSION));
diff --git a/application/portalwebpage.class.inc.php b/application/portalwebpage.class.inc.php
index fe25c056a..bbe39b995 100644
--- a/application/portalwebpage.class.inc.php
+++ b/application/portalwebpage.class.inc.php
@@ -92,6 +92,12 @@ class PortalWebPage extends NiceWebPage
$this->add_linked_script("../js/ajaxfileupload.js");
$this->add_linked_script("../js/ckeditor/ckeditor.js");
$this->add_linked_script("../js/ckeditor/adapters/jquery.js");
+
+ $sJSDisconnectedMessage = json_encode(Dict::S('UI:DisconnectedDlgMessage'));
+ $sJSTitle = json_encode(Dict::S('UI:DisconnectedDlgTitle'));
+ $sJSLoginAgain = json_encode(Dict::S('UI:LoginAgain'));
+ $sJSStayOnThePage = json_encode(Dict::S('UI:StayOnThePage'));
+
$this->add_ready_script(
<<'+$sJSDisconnectedMessage+'').dialog({
+ modal:true,
+ title: $sJSTitle,
+ close: function() { $(this).remove(); },
+ minWidth: 400,
+ buttons: [
+ { text: $sJSLoginAgain, click: function() { window.location.href= GetAbsoluteUrlAppRoot()+'pages/UI.php' } },
+ { text: $sJSStayOnThePage, click: function() { $(this).dialog('close'); } }
+ ]
+ });
+ }
+ });
}
catch(err)
{
diff --git a/dictionaries/de.dictionary.itop.ui.php b/dictionaries/de.dictionary.itop.ui.php
index bbe91fb79..89597f615 100644
--- a/dictionaries/de.dictionary.itop.ui.php
+++ b/dictionaries/de.dictionary.itop.ui.php
@@ -987,5 +987,9 @@ Wenn Aktionen mit Trigger verknüpft sind, bekommt jede Aktion eine Auftragsnumm
'Month-11' => 'November',
'Month-12' => 'Dezember',
'UI:FillAllMandatoryFields' => 'Bitte füllen Sie alle Pflichtfelder',
+ 'UI:DisconnectedDlgMessage' => 'You are disconnected. You must identify yourself to continue using the application.~~',
+ 'UI:DisconnectedDlgTitle' => 'Warning!~~',
+ 'UI:LoginAgain' => 'Login again~~',
+ 'UI:StayOnThePage' => 'Stay on this page~~',
));
?>
diff --git a/dictionaries/dictionary.itop.ui.php b/dictionaries/dictionary.itop.ui.php
index de56913f9..d1ead1914 100644
--- a/dictionaries/dictionary.itop.ui.php
+++ b/dictionaries/dictionary.itop.ui.php
@@ -1240,6 +1240,11 @@ When associated with a trigger, each action is given an "order" number, specifyi
'UI:About:Licenses' => 'Licenses',
'UI:About:Modules' => 'Installed modules',
+ 'UI:DisconnectedDlgMessage' => 'You are disconnected. You must identify yourself to continue using the application.',
+ 'UI:DisconnectedDlgTitle' => 'Warning!',
+ 'UI:LoginAgain' => 'Login again',
+ 'UI:StayOnThePage' => 'Stay on this page',
+
'ExcelExporter:ExportMenu' => 'Excel Export...',
'ExcelExporter:ExportDialogTitle' => 'Excel Export',
'ExcelExporter:ExportButton' => 'Export',
diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php
index 16a5a72a9..97531b3f2 100644
--- a/dictionaries/fr.dictionary.itop.ui.php
+++ b/dictionaries/fr.dictionary.itop.ui.php
@@ -1082,6 +1082,11 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
'UI:About:Licenses' => 'Licences',
'UI:About:Modules' => 'Modules installés',
+ 'UI:DisconnectedDlgMessage' => 'Vous êtes déconnecté(e). Vous devez vous identifier pour pouvoir continuer à utiliser l\'application.',
+ 'UI:DisconnectedDlgTitle' => 'Attention !',
+ 'UI:LoginAgain' => 'S\'identifier',
+ 'UI:StayOnThePage' => 'Rester sur cette page',
+
'ExcelExporter:ExportMenu' => 'Exporter pour Excel...',
'ExcelExporter:ExportDialogTitle' => 'Export au format Excel',
'ExcelExporter:ExportButton' => 'Exporter',