Warn And Log Out User Due To Inactivity In Angular App
Tags: angular, security
Published: 2024-03-28 22:34:32

Protecting sensitive data from unauthorized access is an important aspect to securing a web application. Implementing an automatic log out feature due to an inactive user can help with that. Let’s learn how!

## Package Installation

Install the **@ng-idle/core** package by running the following command:

```
npm install @ng-idle/core
```

## Package Setup

In order to use the package, you need to provide it at the root of the application. Depending on your Angular setup and version, you’ll need to do **one** of the following:

**app.module.ts**

```javascript
import { NgIdleModule } from '@ng-idle/core';
 
@NgModule({
  providers: [
    NgIdleModule.forRoot()
  ]
})
```

**app.config.ts**

```javascript
import { importProvidersFrom } from '@angular/core';
import { NgIdleModule } from '@ng-idle/core';
 
export const appConfig: ApplicationConfig = {
  providers: [
    importProvidersFrom(NgIdleModule.forRoot())
  ]
};
```

## Warn User With App Alert

When the user becomes inactive, let’s provide a warning with a countdown. I’m using Clarity’s [alert component](https://clarity.design/documentation/alert), specifically an app level alert since it appears at the top of the app. Make sure to place it in a location that appears no matter what page you’re on.

```javascript
@if (inactiveUser) {
  <clr-alert [clrAlertAppLevel]="true" [clrAlertClosable]="false" [clrAlertType]="'warning'">
    <clr-alert-item>
      <span class="alert-text">Logging out in {{ inactiveCountdown }} seconds due to inactivity.</span>
    </clr-alert-item>
  </clr-alert>
}
```

We wrap the alert in an if statement and only display it if **inactiveUser** is true. We’ll see how that variable is defined in a moment.

By the way, you can also use **ngIf** on clr-alert instead of **@if** if you’re not yet on an Angular version that supports @if.

## Handle Inactive User

Within your app component, let’s set up everything to handle an inactive user. Let’s start by importing what we need from the @ng-idle/core package.

```javascript
import { DEFAULT_INTERRUPTSOURCES, Idle } from '@ng-idle/core';
```

Create a variable called **idle** for the idle service in the component constructor.

```javascript
constructor(private idle: Idle) {}
```

Within the app component class, create a variable called **inactiveCountdown**, which will be of type number. This will count down the number of seconds before a user times out.

```javascript
inactiveCountdown: number;
```

Create a variable called **inactiveUser**, which will be of type boolean. This will track whether the user is considered inactive or not.

```javascript
inactiveUser: boolean;
```

You’re probably keeping track of when the user is successfully authenticated. This is the right time to start watching for when the user becomes idle or not.

```javascript
if (authenticated) {
  this.idle.watch();
} else {
  this.idle.stop();
}
```

Now let’s create a private method called **handleInactiveUser**.

```javascript
private handleInactiveUser() {
  this.idle.setIdle(300);
  this.idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
  this.idle.setTimeout(15);
 
  this.handleIdleStart();
  this.handleIdleEnd();
  this.handleTimeoutWarning();
  this.handleTimeout();
}
```

- **setIdle** defines the number of seconds before a user is considered idle. So 300 seconds would be 5 minutes.
- **setInterrupts** defines what events will stop a user from being considered idle. We’ll use the default ones like mouse move, key down, etc.
- **setTimeout** defines the number of seconds before a user times out. The user will have 15 seconds to take action before they time out.
- **handleIdleStart** will listen for when the user is considered idle. We will set inactiveUser to true when this happens.
- **handleIdleEnd** will listen for when the user is no longer considered idle. We will set inactiveUser to false when this happens.
- **handleTimeoutWarning** will listen for the countdown. We will set inactiveCountdown to this countdown.
- **handleTimeout** will listen for when the user is considered timed out. We will log the user out at this point.

Let’s create those 4 methods mentioned above.

```javascript
private handleIdleStart() {
  this.idle.onIdleStart.subscribe(() => {
    this.inactiveUser = true;
  });
}
 
private handleIdleEnd() {
  this.idle.onIdleEnd.subscribe(() => {
    this.inactiveUser = false;
  });
}
 
private handleTimeout() {
  this.idle.onTimeout.subscribe(() => {
    this.inactiveUser = false;
    this.logOut();
  });
}
 
private handleTimeoutWarning() {
  this.idle.onTimeoutWarning.subscribe(countdown => {
    this.inactiveCountdown = countdown;
  });
}
```

All that’s left to do is call handleInactiveUser() in ngOnInit.

```javascript
ngOnInit() {
  this.handleInactiveUser();
}
```

Access your application and remain inactive for the number of seconds you defined. You should see the alert appear with the countdown. If you take any action the countdown will stop and the alert will disappear. If you time out, you’ll be logged out automatically!

---
**Visit our website at [https://nightwolf.dev](https://nightwolf.dev) and follow us on [Twitter](https://twitter.com/nightwolfdev)!**