moribvndvs / ng2-idle

Responding to idle users in Angular (not AngularJS) applications.
https://moribvndvs.github.io/ng2-idle
Apache License 2.0
322 stars 129 forks source link

Re-set the idle period setting #191

Closed boomdizz closed 10 months ago

boomdizz commented 1 year ago

Is your feature request related to a problem? Please describe. I want to have the ability to make the idle period re-settable. In particular, this would help our developers as they are frustrated having to re-login often. They would like to set this to a much larger time value in their dev environments, so they don't have to keep logging in often. I can see how some customers might want to customize this setting as well

Describe the solution you'd like When my app loads it loads with a default value (say 5 minutes). But in different environments, I would like to have the ability to set a configurable value for the idle period (say 30 minutes) on the backend, fetch it using a REST API, then re-set the idle period. I have not been able to re-set the idle period successfully. I have tried using stop() and watch() methods to no avail. Is there an existing 'reset' I can do, so that I can specify the idle period a second time? If not, please consider adding this capability.

Describe alternatives you've considered None. Have been living with the initial, hard-coded value for some time now.

Additional context Add any other context or screenshots about the feature request here.

boomdizz commented 1 year ago

Just resetting the idle period using setIdle() to say 30 minutes - the call goes through, but the new idle period does not become effective. Instead the events fire based on the old idle setting.

boomdizz commented 1 year ago

Actually, I am not sure if this is a bug.

I took another approach that failed that suggests there may be a bug here. I have posted the question on stackoverflow. Here is the link: https://stackoverflow.com/questions/76775890/ng-idle-subscriptions-not-working-inside-another-subscription/76776240#76776240 Also copying and pasting it here:

I am using the @ng-idle/core package to implement an idle timeout in my angular 2 application (at angular 14 currently). On exceeding the idle timeout, the code logs the user out. The idle detection and logging out functionality has been written into my app.component.ts file.

When written with a hard-coded value for idle time, the code works perfectly. However, I would like the idle time to be configurable on my backend. Hence I have written a service class that fetches that value from the backend on application load. The rest of the code is exactly the same as the hard-coded idle time version (except that it is now inside the subscribe block of my service subscription). However, the ng-idle subscriptions never fire. The code is as follows:

    constructor(
        private router: Router,
        private idle: Idle, cd: ChangeDetectorRef,
        private authSvc: AuthService,
        private sessionDataSvc: SessionDataService,
        private countdownSvc: CountdownService
      ) {

    // set idle parameters
    this.sessionDataSvc.getSessionProperties().subscribe(( {data} ) => {
      let session_timeout = data.sessionProperties.session_idle_timeout
      // set the idle and timeout values
      // let session_timeout = 30;
      idle.setIdle(session_timeout) // how long can they be inactive before considered idle, in seconds
      idle.setTimeout(this.TIMEOUT); // how long can they be idle before considered timed out, in seconds
      idle.setInterrupts(DEFAULT_INTERRUPTSOURCES); // provide sources that will "interrupt" aka provide events indicating the user is active

      console.log("Setting idle timeout to " + session_timeout + " seconds")

      // Some code snipped for brevity

      // do something when the user has timed out
      idle.onTimeout.subscribe(() => {
        console.log("onTimeout called")
        this.idleState = "TIMED_OUT"
        this.authSvc.logout()
        this.reset()
        this.router.navigate(['login'], { queryParams: { reason: "Session Timeout. Please re-login" } });
      });
      // do something as the timeout countdown does its thing
      });

        console.log("Done with setting idle timeout")
        });
      }

    reset() 
    {
        // we'll call this method when we want to start/reset the idle process
        // reset any component state and be sure to call idle.watch()
        this.idle.watch();
        this.idleState = "NOT_IDLE";
        this.countdown = null;
        this.lastPing = null;
    }

Note, that the ng-idle package has 4 subscription methods - onIdleStart, onIdleEnd, onTimeoutWarning and onTimeout. I have purposefully omitted the first three from the code above, so as to be brief in my writeup - otherwise they exist in the code. The this.sessionDataSvc.getSessionProperties() is working as the console.log message is showing the log message

Setting idle timeout to 30 seconds

is showing in the console log (as is the other log message "Done with setting idle timeout" in the code above). But none of the ng-idle subscriptions are firing.

As I mentioned above, if I was to comment out the lines

this.sessionDataSvc.getSessionProperties().subscribe(( {data} ) => {
  let session_timeout = data.sessionProperties.session_idle_timeout

and enable the line:

// let session_timeout = 30;

instead (this is the hard-coded case), the @ng-idle subscriptions work as designed and documented. So why are they not inside a service subscription?

moribvndvs commented 10 months ago

Is there an actual issue? If you change the settings, you'll need to idle.stop() and idle.watch again for them to take effect. Please note that simply calling watch again will not clear all the old stuff out and start over, it only starts watching if it's not already.