From 9f92e5e0be592bbb4faeb3c668702a1753c01e4f Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 25 Jun 2015 15:32:30 +0000 Subject: [PATCH] #788 Whenever a timeout is detected by an ajax request, a popup dialog warns the user to log-in again. SVN:trunk[3613] --- application/itopwebpage.class.inc.php | 26 +++++++++++++++++++++++++ application/loginwebpage.class.inc.php | 7 +++++++ application/portalwebpage.class.inc.php | 25 ++++++++++++++++++++++++ dictionaries/de.dictionary.itop.ui.php | 4 ++++ dictionaries/dictionary.itop.ui.php | 5 +++++ dictionaries/fr.dictionary.itop.ui.php | 5 +++++ 6 files changed, 72 insertions(+) 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',