Navigate to the logout page automatically when closing the final tab

In order to comply with the requirement, I need to log out the user when they close the last tab on the browser.

    ngOnInit() {
        let counter: any = this.cookieService.get('screenCounterCookie');
        counter ? ++counter : (counter = '1');
        this.cookieService.set('screenCounterCookie', counter);
    }


    @HostListener('window:beforeunload', ['$event'])
    ngOnDestroy() {
        let counter: any = this.cookieService.get('screenCounterCookie');
        if (counter > 1) {
            --counter;
            this.cookieService.set('screenCounterCookie', counter);
        } else {
            this.cookieService.delete('screenCounterCookie');
            window.open(environment.cognitoLogoutURL);
        }
    }

There seems to be inconsistency in the behavior. Sometimes the counter decreases, sometimes it doesn't. Additionally, I need to address the logic for handling refresh, closing of multiple tabs, and browser closure.

What is the best way to implement this?

Answer №1

Monitoring the total number of tabs: https://jsbin.com/mipanuro/1/edit?html,js,output (Please refer to this link for more information)

Approach 1 (Utilizing a POST request):

Implementing BeaconAPI (navigator.sendBeacon()) for background processing.

Approach 2 (Applicable for GET Requests as well):

Utilizing fetch in conjunction with keep-alive

Approach 3 (Websocket Integration):

Sending periodic pings to the backend to maintain session validity. The backend can revoke the session if pings are not received.

Answer №2

I have made some enhancements to your code without utilizing the ngOnDestroy method. Upon testing, it appears to be functioning correctly.

import { Component } from '@angular/core'

@Component({
  selector: 'app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  constructor() {
    const counter = localStorage.getItem('screenCounterCookie') || 0

    localStorage.setItem('screenCounterCookie', (Number(counter) + 1).toString())

    window.addEventListener('beforeunload', () => {
      const counter: number = Number(localStorage.getItem('screenCounterCookie')) - 1
      localStorage.setItem('screenCounterCookie', counter.toString())

      if (counter <= 0) {
        localStorage.removeItem('screenCounterCookie')
        console.log('logout')
        // Your logout
      }
    })
  }
}

Answer №3

One effective method I have considered for achieving this is by utilizing websockets along with the keep-alive principle. Alternatively, you could perform a manual periodic check with the server to refresh a timer that would automatically log out the user upon expiration.

Relying on the browser to trigger an event when it closes or when the user loses power is not a reliable method across different platforms.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Cordova Emulate Android cannot locate Gradle or an installed Android Studio, despite their presence

Error Message After taking a break from the project and returning to it, I encountered an error message that I couldn't resolve no matter what solution I tried. Seeking help here as I know the app itself should be functioning properly. If you are un ...

What could be causing the increased build size of my Polymer2 compared to Angular5?

After reading multiple blogs, I decided to go with the polymer2 framework instead of angular. Some sources claimed that Polymer contributes less to the build size for production compared to angular2/5. To test this theory, I created two demo projects - on ...

The step-by-step guide to fixing a Gigwage client eslint error using nestJS

Whenever I utilize the gigwage client for my services, I encounter the following eslint error: TS2742: The inferred type of 'findAll' cannot be named without a reference to '@gigwage/client/node_modules/axios'. This is likely not porta ...

The error message "SyntaxError: Cannot use import statement outside a module" popped up while working with discord.js, typescript, heroku

// Necessary imports for running the discord bot smoothly import DiscordJS, { TextChannel, Intents, Message, Channel, NewsChannel, ThreadChannel, DiscordAPIError } from 'discord.js' type guildTextBasedChannel = TextChannel | NewsChannel | ThreadC ...

Selecting logic depending on the request body in NestJS

Currently, my controller looks like the following: @Controller("workflow") export class TaskWorkflowController { public constructor( private readonly jobApplicationActivityWorkflow: JobApplicationActivityService ) {} @Post("/:job- ...

The highcharts-angular version of the stock-tools-gui demo is lacking a graphical user interface (GUI)

Attempting to create an Angular version of this impressive demo: https://www.highcharts.com/stock/demo/stock-tools-gui . Utilizing the highcharts-angular wrapper in this project: https://codesandbox.io/s/pjkqwwmkr7 - everything is functional except for t ...

How can I incorporate piping into an input field when working with Angular 2?

Just starting out with angularJS2 and looking to add a pipe to the input type text in a form. For example, if I have an input tag like this <input type="text" class="col-lg-7 small rounded form-control" formControlName="firstName" /> I'd like ...

Exploring the Secrets of JSON Parsing in Angular

In my Angular application, I have the following JSON: var alphas = { "Data": { "1" : { "abc": { "key1":"Value1", "key2":"Value2", ...

The request for PUT, POST, and DELETE methods has been terminated

Issue Encountering the following problem: https://i.sstatic.net/aUF0m.png Scenario Pinning down the exact reason and providing detailed information is proving to be a challenge. In essence, the setup involves an Angular + Express.js application, MySQL f ...

Encountering the error message "Unable to access properties of null (specifically 'useState')" while trying to utilize a component from my custom library

After developing a personalized UI library and style guide to standardize components in my application, all was running smoothly until I incorporated a component utilizing the useState hook. An error consistently surfaces whenever I attempt to use a compo ...

What is the best way to establish a restriction on the number of items obtained from an RSS

I am receiving a feed from this specific link. My goal is to only retrieve the initial five items from the feed, but currently I am getting all of the items. Is there a way for me to specifically request only the first five items? Do I need to include an ...

Utilizing Vue class-style components for creating a recursive component

I'm currently working with a class-style component using the vue-property-decorator plugin. I want to create a recursive component that can use itself within its own structure. Here's a snippet of my code: <template> <ul> <li& ...

Getting the route parameter in Angular 2 is easy with the stable router

Currently working with the latest stable Angular 2 RC version. Unfortunately, the documentation for the new router component has yet to be completed. Struggling to retrieve a parameter from a navigated page. Defined routes: @Routes([ {path: '/resu ...

What steps can I take to achieve complete code coverage in my unit testing for this component and also ensure that the 'else' part is being

I am struggling to figure out how to access the remaining line of code in order to achieve full code coverage. Simply checking if the function has been called (toHaveBeenCalled()) will suffice. Here is a snippet from my TypeScript file and Spec file, alon ...

Angular does not automatically send cookies to the server

Currently, my front-end is built using Angular 15, while the back-end utilizes node.js version 18.10.0 and express version 4.17.2. I encountered an issue where I need to send the cookie stored in my browser back to the originating server. This cookie serv ...

Issues arising with utilizing Github for hosting Angular applications

After developing a site with Angular, everything was running smoothly on my local host. However, when I decided to host the site on GitHub, two errors appeared. You can access my site through this link: Here is a screenshot of the errors encountered [1]: ...

The functionality of "subscribe()" is outdated if utilized with "of(false)"

My editor is flagging the usage of of as deprecated. How can I resolve this issue and get it working with of? public save(): Observable<ISaveResult> | Observable<boolean> { if (this.item) { return this.databaseService.save(this.user ...

Are optional parameters in TypeScript distinct from parameters that have the ability to be undefined?

Is there a distinction between the following two code snippets? function sayHello(name?: string) { if (name) { return 'Hello ' + name; } return 'Hello!'; } and function sayHello(name: string | undefined) { if (name) { return &apo ...

A critical error has occurred: RangeError - The maximum call stack size has been exceeded while trying to

After attempting to filter a list of titles using Ng2SearchPipeModule, I imported the module in app.module.ts and created a new searchbar component. searchbar.component.ts import { FirebaseService } from './../../firebase.service'; import { Ang ...

Validate object containing both static and dynamic keys

I'm attempting to create a Yup validation schema for an object with the following structure: interface myObject { prop0: Date prop1: { nestedProp1: string nestedProp2: number [key: string]: string | number } } This is what I have tr ...