Idle Detection
Idle detection is the process of monitoring user activity and determining when a user becomes inactive. This is particularly useful for applications that require users to remain logged in, as it allows the system to take appropriate action when a user stops interacting with the application, such as warning them of an impending timeout or automatically logging them out after a period of inactivity.
Key Features of the Idle Detection Service
- Configurable Idle and Timeout Durations: The service allows for customization of the idle and timeout durations through the
IdleDetectionConfig
class. - Automatic Reset on User Activity: The service automatically resets the idle timer whenever user activity is detected, ensuring that the user's session remains active.
- Event Emission: The service emits events when the idle period ends and when the countdown to timeout begins, allowing components to take action, such as displaying a warning message to the user.
- Reactive Programming: By using RxJS subjects, the service provides observables that emit events when the user becomes idle or when the countdown ends. This allows components to react to these events in real-time.
Usage
1. Configure idle and timeout durations globally
We provide a configuration class that will hold our idle and timeout durations:
export class IdleDetectionConfig {
idleDurationInSeconds?: number;
timeoutDurationInSeconds?: number;
}
- Idle-detection phase: Suppose you configure
idleDurationInSeconds
to 5 * 60 (5 minutes). From the moment there is no action on the website, you enter this phase. After 5 minutes, the idle detection ends, indicating that you have been idle for a long time (idleDurationInSeconds
). You can subscribe to theonIdleEnd()
observable, which will emit at this moment. Once this phase is completed, you will enter the second phase. - Timeout phase: When you enter this phase, the countdown starts immediately from the value of
timeoutDurationInSeconds
. You can subscribe to theonCountDown()
observable to obtain the countdown value. When the countdown reaches 0, the timeout phase will end. You can subscribe to theonTimeout()
observable to know when the timeout phase ends. At this point, you can log out the user or perform other actions.
To use the idle detection service in an Angular application, you would first provide the configuration in your module:
import { provideIdleDetectionConfig, IdleDetectionService } from 'ngx-lift';
@NgModule({
providers: [
// After 20 minutes of inactivity, a countdown starts with 300.
provideIdleDetectionConfig({
idleDurationInSeconds: 20 * 60, // 20 minutes for idle-detection phase
timeoutDurationInSeconds: 5 * 60, // 5 minutes for timeout phase
}),
],
})
export class AppModule {}
Use in standalone app:
import { provideIdleDetectionConfig } from 'ngx-lift';
export const appConfig: ApplicationConfig = {
providers: [
provideIdleDetectionConfig({ idleDurationInSeconds: 20 * 60, timeoutDurationInSeconds: 5 * 60 }),
],
};
bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));
2. Use IdleDetectionService in your component
Then, in your AppComponent, you can subscribe to the service's observables to react to idle events:
import { IdleDetectionService } from 'ngx-lift';
export class AppComponent implements OnInit {
constructor(private idleDetectionService: IdleDetectionService, private authService: AuthService) {}
ngOnInit() {
if(this.authService.isLoggedIn) {
// setConfig is optional if you have idle configuration by provideIdleDetectionConfig
// This will overwrite the config passed by provideIdleDetectionConfig
this.idleDetectionService.setConfig({
idleDurationInSeconds: 5 * 60,
timeoutDurationInSeconds: 5 * 60,
});
// Most important, start to watch for user inactivity!
this.idleDetectionService.startWatching();
this.idleDetectionService.onIdleEnd().subscribe(() => {
// Handle idle end event, e.g., show a warning dialog
console.log('idle detection phase ends, enter timeout phase');
});
this.idleDetectionService.onTimeoutEnd().subscribe(() => {
// Handle timeout end event, e.g., log out the user
console.log('timeout phase ends, should logout user');
});
this.idleDetectionService.onCountDown().subscribe((countdown) => {
// Update the UI with the remaining time if needed
console.log(countdown, 'display countdown in UI');
});
}
}
ngOnDestroy() {
this.idleDetectionService.clearTimers();
}
}
3. (Optional) Use IdleDetectionComponent
Furthermore, we provide a component in clr-lift
that displays a Clarity modal dialog when the user is idle. The dialog will appear when the idle-detection phase concludes and start counting down. Once the countdown ends, you can hook into the timeout
handler in your component to perform custom logic such as clearing the localStorage token and redirecting the user to the login page.
The parameters idleDurationInSeconds
and timeoutDurationInSeconds
are optional. When these parameters are passed, they will overwrite the configuration passed by provideIdleDetectionConfig
.
import {IdleDetectionComponent} from 'clr-lift';
@Component({
imports: [IdleDetectionComponent],
template: `
if(isLoggedIn) {
<cll-idle-detection [idleDurationInSeconds]="15 * 60" [timeoutDurationInSeconds]="5 * 60" (timeout)="onTimeout()" />
}
`
})
export class AppComponent {
isLoggedIn = inject(AuthService).isLoggedIn;
onTimeout() {
localStorage.removeItem('your-app-jwt');
location.assign('/login');
}
}
The dialog looks like below:
