HOWTO handle portal user idle timeout
Author: Arnaud Leymet
Submitted: 09 May 2008
Abstract
The question has been asked many times. Some solutions came out in the forums, but a few matched correctly the problem.
I'd like to share my solution which works great. This solution is a javascript one, which is located in the banner of the portal (masthead).
Solution
Simply edit the banner par file (com.sap.portal.navigation.masthead.par.bak) by applying the following :
- Create a javascript/ directory in the par structure.
- Add the file customtimeout.js in this directory : this is the customized timeout-handling javascript file.
- Edit the file PORTAL-INF/jsp/HeaderiView.jsp in order to call the timeout handler.
Source
| Do not forget Remove all 'REMOVEME' occurrences in these two files (I had troubles publishing this page on the wiki)! |
/** * Custom Timeout Handler * @param warn_delay Delay until the warning message (in minutes) * @param kick_delay Delay until the "session timed out" message (in minutes) */ var customTimeoutHandler = function(warn_delay, kick_delay) { return { debug_mode: false, // Switches the display of the timer (function _displayTimer) timeout_wait: 1000 * 10, // Delay for the 'setTimeout' native function timeout_warn_delay: 1000 * 60 * warn_delay, // Delay until the warning message timeout_kick_delay: 1000 * 60 * kick_delay, // Delay until the timeout message and the effective timeout /** * Initializes the custom portail timeout (called at first time) **/ initialize: function() { this.updateTimer(); REMOVEMEsetTimeout("timeout_h.checkTimeout()", this.timeout_wait); }, /** * Updates the custom portail timeout (called whenever the user navigates in the portal) **/ updateTimer: function() { var dt = new Date(); writeCookie('custom_timeout', dt.getTime()); if(this.debug_mode) { this._displayTimer(); } }, /** * Checks wether the timeout has occured or not ( repeatedly called) **/ checkTimeout: function() { var now = new Date(); var diff = now.getTime() - this._getTimerStart(); if(diff > this.timeout_warn_delay) { // Action : unactive var date_timeout = new Date(); date_timeout.setTime(this._getTimerStart().getTime() + this.timeout_kick_delay); var date_t_hours = date_timeout.getHours() + ""; if(date_t_hours.length == 1) date_t_hours = "0" + date_t_hours; var date_t_min = date_timeout.getMinutes() + ""; if(date_t_min.length == 1) date_t_min = "0" + date_t_min; var date_timeout_display = date_t_hours + ":" + date_t_min; REMOVEMEalert('The page was idle since '+warn_delay+' minutes.\n'+ 'Clicking on the OK button before '+date_timeout_display+' will reactivate your session.'); now = new Date(); diff = now.getTime() - this._getTimerStart(); if(diff > this.timeout_kick_delay) { // Action : kick (= time out) logoff(); } else { this._refreshPage(); this.updateTimer(); REMOVEMEsetTimeout("timeout_h.checkTimeout()", this.timeout_wait); } } else { REMOVEMEsetTimeout("timeout_h.checkTimeout()", this.timeout_wait); } if(this.debug_mode) { this._displayTimer( diff + " > " + this.timeout_kick_delay + " ? " + (diff > this.timeout_kick_delay) ); } }, /** * */ _getTimerStart: function() { var timeout_start = parseInt(readCookie('custom_timeout')); return new Date(timeout_start); }, /** * Displays the timer informations in the window status bar **/ _displayTimer: function(message) { var dt = this._getTimerStart(); var timer_start_string = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds(); if(message && message!=null && message!="") { window.status = timer_start_string + " - " + message; } else { window.status = timer_start_string; } }, /** * Refreshes the portal page content **/ _refreshPage: function() { try { frameworkSupport.refreshContentArea(); } catch(e) { document.location.reload() } }, /** * Subscribes to an EPCM event **/ addListener: function(urn, action) { EPCM.subscribeEvent(urn, action, this.updateTimer); } } } // cookies functions function writeCookie(name, value) { document.cookie = name + "=" + escape(value); } function readCookie(name) { var arg = name+'='; var alen = arg.length; var clen = document.cookie.length; var i=0; while (i < clen){ var j = i + alen; if (document.cookie.substring(i, j) == arg) return getCookieVal(j); i=document.cookie.indexOf(' ', i) + 1; if (i == 0) break; } return null; } function getCookieVal(offset){ var endstr = document.cookie.indexOf (';', offset); if (endstr == -1) endstr = document.cookie.length; return unescape(document.cookie.substring(offset, endstr)); }
// ...
<REMOVEMEscript type="text/javaREMOVEMEscript"
src="/irj/portalapps/{par_file_name}/javascript/customtimeout.js" >
</script>
<REMOVEMEscript type="text/javaREMOVEMEscript">
var timeout_h = customTimeoutHandler(30, 40);
timeout_h.initialize();
function pop() { timeout_h.updateTimer(); }
EPCM.subscribeEvent("urn:com.sapportals:navigation", "Navigate", pop);
//EPCM.subscribeEvent("urn:com.foo.bar.myapp", "myEvent", pop);
// Subscribe to your events here
</script>
// ...
Don't forget to change the 'par_file_name' string in the latter file and remove all 'REMOVEME' occurrences in these two files (I had troubles publishing this page on the wiki).
Known limitations
This solution has some limitations.
Among them, the most embarassing one is the fact that the timeout timer is only reseted by subscribed events.
Unchanged, it only resets the timer on navigation changes:
EPCM.subscribeEvent("urn:com.sapportals:navigation", "Navigate", pop););
If you want to add events for resetting the timer, you'll have to add this type of lines:
EPCM.subscribeEvent("urn:com.company.my:myservice1", "OnChange", pop);); EPCM.subscribeEvent("urn:com.company.my:myservice2", "OnRequest", pop);); //etc.
Expected result
After being idle on the portal for some time, you shoud obtain a popup like the following:

Hope you'll find it usable!
Comments (28)
Jun 29, 2008
Maurice Lajoie says:
Very nice option! Do you insert this code in the com.sap.portal.runtime.log...Very nice option!
Do you insert this code in the com.sap.portal.runtime.logon.par?
I'm on NetWeaver 2004S sp09.
This is exactly what I'm looking for ... and would like to display html page with message on logout.
Jun 29, 2008
Arnaud Leymet says:
No, you won't be able to use it if your insert this code in a page that isn't al...No, you won't be able to use it if your insert this code in a page that isn't always visible in your portal. Fact is, runtime logon par is used only once, at authentification time.
I recommend inserting it in the banner (default is: com.sap.portal.navigation.masthead.par).
And If you rather prefer displaying a html page on logout rather than a basic popup, you should add the following code in the logout( ) function located in the banner jsp file :
window.open('path/to/my_logout_page.html', 'logout', 'width=200,height=200');That should do the trick !
Jul 03, 2008
Santiago Ruiz Ramos says:
Hello, I was looking for any solution for this theme. I look for in sap note, SD...Hello, I was looking for any solution for this theme. I look for in sap note, SDN forums ... I saw a note 982982, it say that its not possible activate a timeout message if SAP EP is using the SAP Logon Ticket for SSO purposes, so Can I install this solution?.
The EP level is EP 7.00 SP15.
Jul 03, 2008
Arnaud Leymet says:
The note 982982 refers to a session timeout, whereas this solution is client-sid...The note 982982 refers to a session timeout, whereas this solution is client-side only, and doesn't play with the HTTP session.
Fact is, we first used the HTTP session solution. But it had some weird behaviors. For instance, after the user re-authenticates (after a timeout), the portal banner sometimes disappeared...
That's why we implemented this client-side solution that will work as long as its timer is lesser than the HTTP session timeout timer.
Jul 25, 2008
SRK says:
Hi, This is exaclty what we are looking for..But we use web dynpro componet for...Hi,
This is exaclty what we are looking for..But we use web dynpro componet for our applications. Also the time out option is set up is diffrent than the R3 session time out for us. When I was taking to our technical team they mentioned that javascripts can't be invoked from webdynpro environment. Did you come across this scenario.
Appreciate your input.
Thanks and Regards,
SK
Jul 26, 2008
Arnaud Leymet says:
Hello, I don't know about using javascript in web dynpro either. But if you use ...Hello,
I don't know about using javascript in web dynpro either.
But if you use web dynpro components for integrating services in a portal, then you'll have for certain some portal areas which will be in other technologies like htmlb, jsp, etc.
That's why you could insert this snippet into a part of your portal that is always visible during your users' browsing experience. And the banner (masthead) is a perfect fit!
Hope it helps
Sep 24, 2008
Vinayak Landge says:
Hi Arnaud, I have done the same as what you said. I downloaded the file -...Hi Arnaud,
I have done the same as what you said. I downloaded the file -- renamed it -- added customtimeout.js and edited headeriview.jsp -- uploaded to portal. Now when i am creating an iview of that and displaying it gives error. Again i tried creating an iview of masthead file com.sap.portal.navigation.masthead.par this does not shows the error.
Please help. Highly appreciate you work
Thanks & Regards,
Vinayak
Sep 24, 2008
Arnaud Leymet says:
Hi Vinayak, Could you post the mentioned error? Is it a client-side (javascript)...Hi Vinayak,
Could you post the mentioned error?
Is it a client-side (javascript) or server-side (java) error?
Regards
Oct 01, 2008
Darvern Phanthakoun says:
Arnaud - thank you very much for sharing your solution. We're in the process of...Arnaud - thank you very much for sharing your solution.
We're in the process of implementing it. So far, so good...thanks again!
Nov 19, 2008
Rakesh says:
Thanks for the blog. It is a nice alternate solution. When i try to implement t...Thanks for the blog. It is a nice alternate solution.
When i try to implement the blog in EP 7.0, i get some javascript errors at portal startup (it disappears after loading) and i dont get the popups after specified timeout. I created the javascript folder under the root par file structure (not in dist or portal-inf). In HeaderiView.jsp, i added the par file name as com.sample.masthead (Do i need to add the .par extension?) .
Can you suggest what might be the problem with my implementation?
Thanks
Rakesh
Apr 21, 2009
Chandu Cheeti says:
We have inserted the code in the com.sap.portal.navigation.masthead.par fil...We have inserted the code in the com.sap.portal.navigation.masthead.par file and reloaded the par file. The alerts are working, but the problem is we are getting alerts even when users are actually using the sytem.
Any ideas why it is behaving like this?
Thanks in advance,
Chandu
Apr 21, 2009
Arnaud Leymet says:
@Rakesh: Sorry I didn't see your comment earlier, but seems to me that you shoul...@Rakesh: Sorry I didn't see your comment earlier, but seems to me that you should debug the javascript with tools like Visual Web Developer Express.
You may have left some of the "REMOVEME" occurrences
@Chandu: There some limitations with this solution ; these are described on the wiki page.
Among them, the most embarassing one is the fact that the timeout timer is only reseted by subscribed events.
It means that, by default, timeout will occur even if the user is "active" but doesn't navigates from a page to another!
Sep 30, 2009
Mitulkumar Patel says:
@Arnaud Leymet is there any work around to limitation, user should not log out ...@Arnaud Leymet
is there any work around to limitation, user should not log out or get the message when they are working on the page but not navigates to other pages... any EPCM event ? or do we have to develop custom EPCM event for that?
Thanks
Sep 30, 2009
Arnaud Leymet says:
@ Mitulkumar P My customer had the same question and I couldn't find an event g...@ Mitulkumar P
My customer had the same question and I couldn't find an event generic enough for matching my needs.
So we had to create some custom events that we subscribed to.
If you can think of a better approach, I'd be really interested!
Regards
Oct 06, 2009
Mitulkumar Patel says:
@ Arnaud Leymet Try this events ... //events raised by load or reload the page ...@ Arnaud Leymet
Try this events ...
//events raised by load or reload the page
EPCM.subscribeEvent( "urn:com.sapportals.portal:pageBuilder", "*", pop );
// events raised by the user actions
EPCM.subscribeEvent( "urn:com.sapportals.portal:user"', ''*'',pop);
fyi: i have not finished my coding yet.. so didnt get chace to test them.. but if you get sucess let me know.. because above events should take care all user activity other then nevigation (which you already suggested)...
Feb 10, 2010
Pavanmeet Dua says:
Hi Arnaud, This is a nice post! . I did the same thing as u mentione...Hi Arnaud,
This is a nice post! .
I did the same thing as u mentioned. Renamed the par file. Added the javascript folder with the customtimeout.js file. Modifield the JSP
i.e added those lines in the bottom of jsp file. Now I do a get a popup box with message that the page was idle for 10 mins. Please click on OK before 10:56 to reactivate the session.
So when I click on the ok before 10:56 it keeps the session alive. But after 10:56 it does not log off on its own and still keeps the session alive. and waits for the user to click on OK to logoff.
Is this a normal behaviour - as i was expecting it to get logged off completely on its own after 10:56.
Please advise.
Thanks,
Pavanmeet
Feb 10, 2010
Arnaud Leymet says:
Hi Pavanmeet, You sure can achieve this goal by replacing the "alert" with a cu...Hi Pavanmeet,
You sure can achieve this goal by replacing the "alert" with a custom HTML popup.
By the way, it's exactly what I did for a client and it works pretty well, with an automatic log off when the timer expires.
Regards
Arnaud
Feb 15, 2010
Pavanmeet Dua says:
Hi Arnaud, Thanks for your quick response. Did you mean you implemented the au...Hi Arnaud,
Thanks for your quick response.
Did you mean you implemented the automatic log off with the "alert" and it worked fine with your client.
I actually debugged it and found out that the code freezes until the alert is clicked 'ok' ( more like a modal window)
and below that is the code for logoff gets executed when the user clicks 'ok'
if(diff > this.timeout_kick_delay)
So until the window is closed or pressed ok .. the below code does not execute and the logoff does not happen.
And I was wondering even if i use a Window with HTML how would that help as I cannot implement a modeless window since the code would open a window and move to the next line and would never satisfy the if condition.
I would appreciate if you can send me the par file which you implemented and it worked fine I tried everything to make it work but does not help.
Thanks alot for your help!
Pavanmeet
Feb 16, 2010
Arnaud Leymet says:
You're welcome. You can find the latest version of this snippet on my github ac...You're welcome.
You can find the latest version of this snippet on my github account: http://github.com/arnaud/sap-ep
This version allows using a non-modal HTML popup so the feature can be used very gracefully
Any ideas & improvements are welcome!
Regards
Arnaud
Feb 17, 2010
Stephan Scholtes says:
Hi Arnaud, thank you very much for this great code example! I've impl...Hi Arnaud,
thank you very much for this great code example! I've implemented it in our testportal and it works very well
I have two questions about improvements:
1. Do you have in the meantime a solution for the given limitations to fetch all user events? It is not really urgent but nice to have
2. Is there an easy possibility to show the logout popup in the users chosen portal language?
Thanks in advance & best regards
Stephan
Feb 17, 2010
Arnaud Leymet says:
Stephan, 1. You may want to try the method of Mitulkumar Patel. I didn't have t...Stephan,
1. You may want to try the method of Mitulkumar Patel. I didn't have time to test it but it seems interesting enough to give it a try.
2. Of course you can internationalize the logout popup. In order to do that, you should use a JSP and .properties files. More about this at http://help.sap.com/saphelp_nw2004s/helpdata/en/42/9381b4a5061d69e10000000a1553f6/frameset.htm
Good luck
Arnaud
Feb 18, 2010
Stephan Scholtes says:
Thank you! Switching the HTML file to an JSP file was the right hint. &nbs...Thank you! Switching the HTML file to an JSP file was the right hint.
I've tested the recommendations of Mitulkumar, but unfortunately they didn't work.
@Mitulkumar: Do you have some experience in the meantime with your suggestions?
Kind regards
Stephan
Apr 28, 2010
Jo Crombie says:
Hi, Great demo thanks! My timeout counts down as expected but it fails to ...Hi,
Great demo thanks!
My timeout counts down as expected but it fails to log off, the screen just refreshes. Any ideas?
Cheers,
Russ.
Dec 30, 2010
sridevi karampudi says:
Hi, Sometimes I am able to see the alert pop-up, sometimes after time reaches a...Hi,
Sometimes I am able to see the alert pop-up, sometimes after time reaches also unable to ....
I thought may be the timer is not getting refreshed, So I added those to lines ,with addition to Navigation event like this:
EPCM.subscribeEvent("urn:com.sapportals:navigation", "Navigate", pop););
EPCM.subscribeEvent("urn:com.company.my:myservice1", "OnChange", pop););
EPCM.subscribeEvent("urn:com.company.my:myservice2", "OnRequest", pop););
So can I cal all the events like this? Please help me .
Any ideas?
Cheers
Sridevi
Dec 30, 2010
Arnaud Leymet says:
Hi Sridevi, If the popup doesn't pops up, then there must be a defect in t...Hi Sridevi,
If the popup doesn't pops up, then there must be a defect in the javascript code running on the browser. You won't fix it with additional events subscriptions for sure.
I recommend that, when in such a situation, you try to debug the javascript right from the IE navigation bar, so that you can check the presence and values of the different variables and methods.
I wish you my best!
Cheers
Arnaud
Mar 30, 2011
Vishal Gupta says:
Hi Arnaud, I have implement this solution but I am Facing the said Web Dynpro a...Hi Arnaud,
I have implement this solution but I am Facing the said Web Dynpro application.
to overcome this I do 2 things
1) As suggested by MitulKumar I added following
EPCM.subscribeEvent("urn:com.sapportals.portal:pageBuilder", "*", pop);
EPCM.subscribeEvent("urn:com.sapportals.portal:user", "*", pop);
2) I also comment the following line in the script: this._refreshPage();
But still the page is getting refreshed.
Any workaround for this?
Aug 02, 2011
David Fryda says:
Hi everyone, Problem : the page gets refreshed. How did u get this work to log...Hi everyone,
Problem : the page gets refreshed.
How did u get this work to logoff from portal ?
Thanks.
Mar 26
Dan Spitzig says:
Hi everyone, Great post. We have successfully implemented this but needed to&n...Hi everyone,
Great post.
We have successfully implemented this but needed to make some changes to meet requirements for accessibility. If the alert pop-up appears and the user reacts in time, the user should be able to continue. If they do not react in time, the current page should be refreshed.
The way my code works right now:
If the user is active in a session, after the allotted time without a navigation change, the popup will appear with the following possible results:
ISSUE: Popup should not appear. I am looking for an EPCM event that I can subscribe to, to trigger the popup reset. EPCM.subscribeEvent("urn:com.sapportals.portal:user", "*", pop); suggested above link does not do it.
ISSUE: Same as above.
If the user in inactive in the session, after the allotted time, the pop-up will appear with the following results:
ISSUE: Session timeout cookie is not reset.
ISSUE: None.
Questions:
Any help would be very much appreciated.
Dan