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

Configure Timeout to not check for idle, just countdown #192

Closed Eldorados closed 11 months ago

Eldorados commented 11 months ago

I guess I could simply do this myself if I set setTimeout to false and then ran my own timer

But would like to run the idle timer for say 20mins where if user is idle then I popup a box asking user to continue or cancel, after the initial idle period I don't want/need to track if they are idle anymore, I now have a dialog box open that has a new 10min timer where they must make a choice or will be automatically logged out when 10mins is up - regardless if they are still idle or not

It would be handy if I could use the timeout timer to do this, but if user is moving the mouse around then the timer resets, I want the timer to run regardless

Is this currently possible to do with the library? A feasible feature to add?

reunefe commented 11 months ago

This is actually doable with the current implementation. I implemented my entire logic in a service with a initialize method. The method itself is triggered in the constructor of my AppModule:

public initialize(): void {
    this.idleService.setIdle(10 * 60); // 10 minutes
    this.idleService.setTimeout(200 * 60); // 20 minutes - starts running after user is idle
    this.idleService.setAutoResume(AutoResume.notIdle); <= this part is key to keep the timeout running even if idling stops
    this.idleService.setInterrupts(DEFAULT_INTERRUPTSOURCES);

    this.idleService.onIdleStart
        .pipe(
            // switchmap to open modal and return its result to stay logged in or log out as observable
        )
        .subscribe() => {
            // confirm logout
                this.authService.logout();
            } else {
                this.idleService.watch();
            }
        })

    // restart the check on idling and thus time out again
    this.idleService.onIdleEnd.subscribe(() => this.idleService.watch(true))

    this.idleService.onTimeoutWarning.subscribe(value => // update popup with time until expiration)

    this.idleService.onTimeout.subscribe(() => this.authService.logout())

    this.idleService.watch();
}
Eldorados commented 11 months ago

This is actually doable with the current implementation. I implemented my entire logic in a service with a initialize method. The method itself is triggered in the constructor of my AppModule:

`public initialize(): void { this.idleService.setIdle(10 60); // 10 minutes this.idleService.setTimeout(200 60); // 20 minutes - starts running after user is idle this.idleService.setAutoResume(AutoResume.notIdle); <= this part is key to keep the timeout running even if idling stops this.idleService.setInterrupts(DEFAULT_INTERRUPTSOURCES);

this.idleService.onIdleStart
  .pipe(
      // switchmap to open modal and return its result to stay logged in or log out as observable
  )
  .subscribe() => {
      // confirm logout
          this.authService.logout();
      } else {
          this.idleService.watch();
      }
  })

// restart the check on idling and thus time out again
this.idleService.onIdleEnd.subscribe(() => this.idleService.watch(true))

this.idleService.onTimeoutWarning.subscribe(value => // update popup with time until expiration)

this.idleService.onTimeout.subscribe(() => this.authService.logout())

this.idleService.watch();

Amazing thanks, I'll give it a try

I wasn't aware of this AutoResume option, we could use some better documentation

reunefe commented 11 months ago

Yeah, I struggled with this exact same thing also this morning when I was trying to achieve this. Saw the option and just tested it out (console.log is my best friend 🙈 ).

But indeed the documentation could really improve drastically

Eldorados commented 11 months ago

One other question, I see you use the skipExpiry set to true only when idle ends, what does that do and why only then?

reunefe commented 11 months ago

That's needed to avoid resetting the timeout, if I'm not mistaken. Otherwise the timeout would also be reset to the initial value (in my case 20 minutes).

My entire use case was:

  • after 10 minutes of idle time I want a pop up
  • user needs to explicitly confirm he wants to stay active
    • by closing the pop up
    • by confirming the pop up
  • user can directly logout from the pop up
  • if user remains idle for a total of 30 minutes, he just be automatically logged out
  • if user does not close the pop up, but moves his mouse, the timer keeps counting down

In the code snippet I'm triggering the watch 3 times:

For example say the timeout timer would already be down to 5 minutes when the user moves his mouse in the browser. That means he is no longer idle and in theory our entire tracking would restart.

moribvndvs commented 11 months ago

Thanks stepping in @reunefe. Just be aware onTimeoutWarning will emit an event each second that ticks down until it times out. The original use case was once they go idle, show a dialog telling them how many seconds until they will be logged out, wherein if they interact with the app again it would be shooed away and return them from being idle.

As for documentation, yes. When I ported this from AngularJS to Angular 2+, I didn't bring the wiki along. I did start a new /docs app in the repo which is published when released where we can include various recipes along with actual documentation, but only got so far as a basic example that you can see now. I'd be happy to take PRs to fill out the documentation. I've been trying to get someone to take over maintenance for years now but it hasn't stuck; I haven't actively developed on Angular in years.

Anyway, it sounds like the ask was to just disable the auto resume functionality, which @reunefe has covered correctly. Reopen if that doesn't appear to function correctly.