Implement Idle Timeout in Angular

Sarmitha Krishnagobal - Aug 21 - - Dev Community

In today's web applications, staying logged in on a website for an extended period, whether an hour or two, can pose security risks. During this time, background API calls might still be running, and if you're not actively using the site, someone else could potentially access it with your credentials. To mitigate these risks and reduce unnecessary server requests, it's crucial to monitor user activity, such as cursor movement or key presses. If the system detects inactivity for a specified duration, it can automatically log the user out. This feature, known as Idle Timeout, is essential for modern web applications.

Let’s dive into implementing idle timeout in Angular.

idleService.ts

import { Injectable } from '@angular/core';
import { interval, Observable, Subject, Subscription, throttle } from 'rxjs';

export class IdleService {
  private idleSubject = new Subject<boolean>();
  private timeout = 1200; //seconds
  private lastActivity?: Date;
  private idleCheckInterval = 600; //seconds
  private idleSubscription?: Subscription

  constructor() { 
    this.resetTimer();
    this.startWatching();
  }

  get idleState(): Observable<boolean> {
    return this.idleSubject.asObservable();
  }

  private startWatching(): void {
    this.idleSubscription = interval(this.idleCheckInterval * 1000)
    .pipe(throttle(() => interval(1000)))
    .subscribe(() => {
      const now = new Date();

      if (now.getTime() - this.lastActivity?.getTime()! > this.timeout * 1000) {
        this.idleSubject.next(true);
      }
    });
  }

  resetTimer(): void {
    this.lastActivity = new Date();
    this.idleSubject.next(false);
  }

  stopWatching(): void {
    if (this.idleSubscription) {
      this.idleSubscription.unsubscribe();
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This service monitors user activity and checks if the user has been idle for a specified duration. If so, it triggers an event through idleSubject

app.component.ts

import { inject, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { IdleService } from 'path-to-your-idleService';

export class AppComponent implements OnInit, OnDestroy {
private idleSubscription?: Subscription;
private idleService = inject(IdleService); 

ngOnInit(): void {
   this.idleSubscription = this.idleService.idleState.subscribe((isIdle) => {     
      if (isIdle) {
        console.log("user is idle");
        // Add logic for handling idle state, e.g., logging out
      } else {
       console.log("user is active");
     }
    });   
}

onUserAction(): void {
    this.idleService.resetTimer();
}

ngOnDestroy(): void {
    if (this.idleSubscription) {
      this.idleSubscription.unsubscribe();
    }
}
Enter fullscreen mode Exit fullscreen mode

Subscribes to the idle state and handles the user being idle or active. It also resets the idle timer on user interactions such as mouse movements, clicks, or key presses.

app.component.html

<div  
    (mousemove)="onUserAction()"
    (click)="onUserAction()"
    (keypress)="onUserAction()"
>
    <router-outlet />
</div>
Enter fullscreen mode Exit fullscreen mode

Captures user interactions to reset the idle timer whenever activity is detected.

. .
Terabox Video Player