Creating a universal timer at the application level in Angular

Is there a way to implement a timer that will automatically execute the logout() function in my authentication.service at a specific time, regardless of which page I am currently on within my application?

I attempted to create a timer within my AuthenticationService, but encountered an issue where the timer would be lost if I redirected to another page.

authentication.service:

@Injectable()
export class AuthenticationService {
  ticks =0;
    timer :Observable<number>;
  constructor(private http: Http, private _JwtHelper: JwtHelper, private router: Router) {
  }

  isLoggedIn() {
    console.log('authentication service islogged in called ')
    let token = localStorage.getItem('token');
    if (!token) { return false; }
    else {
      return true;
    }
  }

  login(credentials) {
    return this.http.post('http://somthing/api/login/login',
      credentials)
      .map(response => {
        let result = response.json();
        if (result && result.token) {
          localStorage.setItem('token', result.token);

           this.timer = Observable.timer(7000,1000);
    this.timer.subscribe(t=> {
        this.func(this);
    });


          return true;
        }
        return false;
      });
  }
func(t){
   this.logout();
   t.unsubscribe();
}
  logout(): void {

    localStorage.removeItem('token');
    this.router.navigate(['/login']);

  }

}

I considered implementing the timer within app.component, but I only want to subscribe to the timer when the login function of the authentication service is called from the login form.

Answer №1

To enhance security measures, one effective method is to store the calculated logout time in localStorage during the login process. In the constructor, the timer can be started using the stored logout time or a default value if none exists.

@Injectable()
export class AuthenticationService {
  ticks =0;
  timer :Observable<number>;

  constructor(private http: Http, private _JwtHelper: JwtHelper, private router: Router) {
    const logoutTime = localStorage.getItem('logoutTime') || Date.now() + 7000;
    this.startTimer(logoutTime);
  }

  isLoggedIn() {
    console.log('authentication service islogged in called ')
    let token = localStorage.getItem('token');
    if (!token) { return false; }
    else {
      return true;
    }
  }

  login(credentials) {
    return this.http.post('http://somthing/api/login/login',
      credentials)
      .map(response => {
        let result = response.json();
        if (result && result.token) {
          localStorage.setItem('token', result.token);
          localStorage.setItem('logoutTime', Date.now() + 7000);
          this.startTimer(Date.now() + 7000);
          return true;
        }
        return false;
      });
  }

  startTimer(time) {
    this.timer = Observable.timer(time);
    this.timer.subscribe(t=> {
      this.func(this);
    });
  }

  func(t){
      this.logout();
      t.unsubscribe();
  }

  logout(): void {

    localStorage.removeItem('token');
    localStorage.removeItem('logoutTime');
    this.router.navigate(['/login']);

  }

}

Answer №2

I managed to resolve the issue by developing:

CanActivateViaAuthGuard.service

@Injectable()
export class CanActivateViaAuthGuard implements CanActivate {

  constructor(private authService: AuthenticationService, private router: Router) {}

  canActivate() {         

        if(this.authService.isLoggedIn()==false ){
            this.router.navigate(['/login']);
            return false;
        }
        else{
            return true;
        }
  }
}

authentication.service:

 isLoggedIn() {

let token = localStorage.getItem('token');
if (!token) { return false; }
else {
  this.setTimeOutTimer();
  return true;
}
  }



setTimeOutTimer() {
    console.log('**setTimeOutTimer**')
    if(this.sub){
      this.sub.unsubscribe();
    }
 let expiry=this.currentUser.exp;

    this.timer = Observable.timer(1000, 1000);

    this.sub = this.timer.subscribe(t => {
      let timenow= moment().format('X'); 
      console.log(expiry + ' '+timenow );
      if(expiry<timenow){

        this.sub.unsubscribe();
      this.logout();

      }
    });
  }


get currentUser() {
    let token = localStorage.getItem('token');
    if (!token) return null;
    return this._JwtHelper.decodeToken(token);
  }

routes:

const routes: Routes = [
  {path: '', canActivate:[CanActivateViaAuthGuard], children:[
    {path:'home', component: HomeComponent},//,canActivate:[CanActivateViaAuthGuard]
    {path:'dummy', component: DummyComponent},...
    ...
    ...

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

Is there a way to enable autofill functionality if an email already exists in the database or API within Angular 12?

In order to auto-fill all required input fields if the email already exists in the database, I am looking for a way to implement this feature using API in Angular. Any guidance or suggestions on how to achieve this would be greatly appreciated. ...

Occasionally, the translate.get function may return the key instead of the intended

I recently encountered an issue while working on a web application built with Angular 12 and ASP.NET Core 5. The application utilizes ngx-translate for internationalization, but I faced a problem with translating content in a new component that I added to ...

Can someone provide guidance on utilizing parentheses in HTML code?

I am facing an issue in my Angular project while using the WordPress API. The problem lies in the API address structure which includes "" like this: <img src="{{importantvideo.better_featured_image.media_details.sizes.["covernews-med ...

The minimum and maximum limits of the Ionic datepicker do not function properly when selecting the month and day

Recently, I have been experimenting with the Ionic 2 datepicker. While the datepicker itself works perfectly fine, I've run into some issues when trying to set the min and max properties. <ion-datetime displayFormat="DD-MM-YYYY" [min]="event.date ...

What is the reason behind the Typescript compiler not converting .ts files to .js files automatically?

Displayed below are the folders on the left showcasing my Typescript file in /src (blue) compiled into Javascript in /dist (purple) using tsc. https://i.stack.imgur.com/7XNkU.png In the source file on the left, there is a reference to a .ts module file t ...

Exploring the TypeScript compiler API to read and make updates to objects is an interesting

I'm delving into the world of the typescript compiler API and it seems like there's something I am overlooking. I am trying to find a way to update a specific object in a .ts file using the compiler API. Current file - some-constant.ts export co ...

VS Code sees JavaScript files as if they were Typescript

I have recently delved into the world of Typescript and have been using it for a few days now. Everything seems to be working smoothly - Emmet, linting, etc. However, I've encountered an issue when trying to open my older JavaScript projects in VS Cod ...

Creating a List programatically in material-ui can be easily achieved by following these steps

I am attempting to create a contact view using the list component from Material-UI. My code is written in typescript, but I am struggling with setting up react and material-ui correctly. Any guidance would be greatly appreciated. export interface IConta ...

Can a JavaScript object be created in TypeScript?

Looking for a way to utilize an existing JavaScript "class" within an Angular2 component written in TypeScript? The class is currently defined as follows: function Person(name, age) { this.name = name; this.age = age; } Despite the fact that Java ...

Having difficulty maintaining trailing zeroes in decimals after converting to float in Angular

I need assistance with converting a string to float in Angular. Whenever I use parseFloat, it seems to remove the zeros from the decimal values. How can I ensure that these zeros are retained with the numerical values? The example below should provide more ...

When the keyboard appears, the Ionic 2 form smoothly slides upwards

I am currently working with the most recent version of Ionic 2. In my code, I have a <ion-content padding><form></form></ion-content> containing a text input. However, when attempting to enter text on an Android device, the keyboard ...

Change object values to capital letters

Upon retrieving myObject with JSON.stringify, I am now looking to convert all the values (excluding keys) to uppercase. In TypeScript, what would be the best way to accomplish this? myObj = { "name":"John", "age":30, "cars": [ { "name":"Ford", ...

Managing user sessions in Angular 5: Best practices and tips

Using the Spring Framework with 'Shiro' for authentication on the backend, And Angular 5 on the frontend. Calling the login API from Postman results in the same user session until the logout API is used, which is expected behavior. Postman UI ...

"Efficiently Distributing HTTP Requests Among Simultaneous Observers using RxJS

Currently, I am working on a feature in my Angular application that requires handling multiple concurrent fetches for the same data with only one HTTP request being made. This request should be shared among all the subscribers who are requesting the data s ...

Navigate to a different component within Angular

Is there a way in Angular to scroll to a component using a button placed in another component? Below is the code snippet for the first component: <div id='banner' class="col-5 offset-1 d-flex justify-content-center align-items-cen ...

Leveraging RXJS Observables and Subjects in combination with Redux is an effective strategy for efficiently managing and processing data

My current project involves utilizing a redux architecture alongside Observables. It has come to my attention that I need to handle data processing after retrieving data from various asynchronous sources. The process is intended to function as follows: ...

What is the purpose of the forwardRef function in React?

I've been working on creating a HOC (higher order component) that assists in conditional rendering. Here is the snippet of code I have so far: interface ConditionalProps { renderIf?: boolean } const ConditionalizeComponent = <Props,>( Origi ...

Finding a solution to the dilemma of which comes first, the chicken or the egg, when it comes to using `tsc

My folder structure consists of: dist/ src/ In the src directory, I have my .ts files and in dist, I keep my .js files. (My tsconfig.json file specifies "outDir":"dist" and includes 'src'). Please note that 'dist' is listed in my git ...

Is it possible to utilize the HttpXsrfInterceptor and HttpXsrfCookieExtractor classes for CSRF configuration in Angular 16, despite Intelli-J indicating that they do not exist?

In a valuable article about configuring CSRF for Angular, two options are outlined: First: opt for the default Csrf configuration: providers: [ { provide: HTTP_INTERCEPTORS, useExisting: **HttpXsrfInterceptor**, multi: true } ] Second: If you're usi ...

Material UI autocomplete is not detecting the options parameter as an array

I am currently working on implementing an autocomplete field that retrieves options from my component's state, which in turn fetches data from the backend. Here is a snippet of my component: export const Person: React.FC<PersonProps> = ({name, a ...