0

I'm programming a React App giving access to some Admin pages. I use react-idle-timer to force a redirection to homepage after an idle of 15 minutes. That works well. Except if the system fall asleep. Then the code seems to work (according to the console), but the Chrome tab freeze on the last render and it can't be close. We can't close the browser either (except by force quit).

The user status is linked to a session ID stored in the cookie. The cookie's life is 30 minutes. If it happens, a redirection will occur on the next database call.

So, the automatic session disconnection process is: 1- 15 minutes idle in admin pages or 30 minutes without database calls. 2- Clear session cookie. 3- Modify session status in database. 4- Fetch new session data from the database. 5- Redirect to homepage.

I though the OS was disconnected from the internet, so I used navigator.onLine to tell me if I'm still connected. It seems I'm still connected.

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import IdleTimer from 'react-idle-timer';
import wakeEvent from 'wake-event';

import { readSessionId, readSessionIdDate } from './cookieUtils';

class AdminLayout extends React.Component {
  constructor(props) {
    super(props);

    this.idleTimer = null;
    this._15minutes = 1000 * 60 * 15
    this.sessionId = readSessionId();
  }

  onIdle = () => {
    if(typeof navigator !== 'undefined' && navigator.onLine) { 
      const
        now = new Date(),
        sessionIdDate = readSessionIdDate(),
        date = sessionIdDate ? new Date(sessionIdDate) : null;

      if(!date || (now - date) > this._15minutes) {
        this.idleTimer.pause();
        this.props.logout();
      }
    } else {
      this.idleTimer.pause();
      wakeEvent(() => {
        const 
          now = new Date(),
          sessionId = readSessionId(),
          sessionIdDate = readSessionIdDate(),
          date = sessionIdDate ? new Date(sessionIdDate) : null;

        if(sessionId === this.sessionId) {
          if(!date || (now - date) > this._15minutes) {
            this.props.logout();
          }
        } else {
          this.props.history.push(`/`)
        }
      });
    }
  };

  render() {
    return (
      <div class="AdminLatout">
        <IdleTimer
          ref={ref => { this.idleTimer = ref }}
          element={document}
          onIdle={onIdle}
          debounce={250}
          timeout={_15minutes}
        />
        <div>
          {content}
        </div>
      </div>
    )
  }
}

export default AdminLayout;

The React App should be redirected to the homepage. Either while sleep mode or on awake event.

  • Why you attach wake event handler in onIdle? It doesn't make sense because with these 2 libraries you cannot have an intersection where both system went to sleep and user was idle. One will happen before the other. Let's say you have 15mins idle time, system went to sleep at 5th min and slept for 30 mins. You opened the browser back, after 10 more minutes, onIdle will be called. Because it's using setTimeout and setTimeout execution is delayed by system sleep – Doğancan Arabacı Jul 15 '19 at 15:25
  • @DoğancanArabacı - After many test, I noticed that the 15 minutes Idle action was triggered during sleep mode. I console.logged timestamp to prove it. So, I though it freezed because there was no internet connection. Then I verified the navigator.onLine thinking it will detect an activated sleep mode. I used the wakeEvent to wait for system waking before triggering the logout process. As you noticed, this attempt failed. –  Jul 15 '19 at 17:44

0 Answers0