Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

inactivity logout in Aurelia app

tl;dr, with Aurelia, how can I call a function that is inside of a view-model from outside of the view-model?

I need to perform a client-side logout on a user that hasn't performed an action (route change, request to server, etc) for a period of time. After reading this GitHub issue I created an inactivity-logout view and view-model and have that incorporated into my app.html and in my attached() function, I start my timer and log the user out when the time expires.

This all works great but I've run into a problem that makes me feel like all of that was a huge rabbit-hole. How do I call my resetInactivityTimer() function from outside of the view-model, is it possible to make one function in a class publicly invokeable? Like when a request to the server is performed, I want to call the resetInactivityTimer() function from my service class

inactivity-logout.ts

import {Aurelia} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {inject} from 'aurelia-dependency-injection';

@inject(Aurelia, Router)
export class InactivityLogout {
    inactivityWarningDuration: number; // how long should the warning be up
    initialInactivityWarningDuration: number; // how long should the warning be up
    inactivityDuration: number; // how long before we warn them
    inactivityIntervalHandle: any;

    constructor(aurelia, router) {
        this.aurelia = aurelia;
        this.router = router;
        this.initialInactivityWarningDuration = 5;
        this.inactivityWarningDuration = this.initialInactivityWarningDuration;
        this.inactivityDuration = 5;
    }

    attached() {
        this.queueInactivityTimer();
    }

    resetInactivityTimer(){
        $("#LogoutWarningPopup").modal("hide"); 

        this.inactivityWarningDuration = this.initialInactivityWarningDuration;
        clearInterval(this.warningInterval);
        this.queueInactivityTimer();
    }

    queueInactivityTimer(){
        clearTimeout(this.inactivityIntervalHandle);

        this.inactivityIntervalHandle = setTimeout(() => {
            this.displayWarning();
        }, 1000 * this.inactivityDuration);
    }

    displayWarning(){
        $("#LogoutWarningPopup").modal({ backdrop: 'static', keyboard: false });
        this.warningInterval = setInterval(()=>{
                this.inactivityWarningDuration--;
                if(this.inactivityWarningDuration <= 0){
                    clearInterval(this.warningInterval);
                    this.logout();
                }
            }, 1000); //start counting down the timer
    }

    logout(){
        $("#LogoutWarningPopup").modal("hide");
        console.log("due to inactivity, you've been logged out.")
        this.aurelia.setRoot('views/login');
    }
}

app.html

    <require from='./inactivity-logout.js'></require>
    <inactivity-logout></inactivity-logout>

search-service.ts

    performSearch(searchText: String) {

        /*
         * Stuff here to reset inactivity timer 
         */

        return this.httpClient.put("/api/Search", searchText)
           .then(response => {
               return response;
           });
    }
like image 521
BSSchwarzkopf Avatar asked Jun 29 '16 13:06

BSSchwarzkopf


1 Answers

The good way for global events is to use PubSub pattern with aurelia-event-aggregator lib.

import {Aurelia} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {inject} from 'aurelia-dependency-injection';
import {EventAggregator} from 'aurelia-event-aggregator';

@inject(Aurelia, Router, EventAggregator)
export class InactivityLogout {
    inactivityWarningDuration: number; // how long should the warning be up
    initialInactivityWarningDuration: number; // how long should the warning be up
    inactivityDuration: number; // how long before we warn them
    inactivityIntervalHandle: any;

    constructor(aurelia, router, ea) {
        this.aurelia = aurelia;
        this.router = router;
        this.initialInactivityWarningDuration = 5;
        this.inactivityWarningDuration = this.initialInactivityWarningDuration;
        this.inactivityDuration = 5;
        this.ea = ea;
        
        // subscribe
        this.sub = this.ea.subscribe(RefreshInactivity, msg => {
           console.log(msg.value);
        });

        // to unsubscribe somewhere
        // this.sub.dispose()
    }
...

}

export class RefreshInactivity {
  
  constructor(value) {
    this.value = value;
  }
  
}

dispatch event somewhere in app

 this.ea.publish(new RefreshInactivity('some value'));
like image 121
valichek Avatar answered Oct 15 '22 02:10

valichek