| /******************************************************************************** |
| * Copyright (c) 2020 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0 |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| ********************************************************************************/ |
| |
| import {DOCUMENT} from "@angular/common"; |
| import {Inject, Injectable} from "@angular/core"; |
| import {Actions, createEffect, ofType} from "@ngrx/effects"; |
| import {Observable, race, timer} from "rxjs"; |
| import {endWith, repeat, switchMap, takeWhile} from "rxjs/operators"; |
| import {AuthService, CoreApiService} from "../../../core"; |
| import {fromReturningToBrowserTabEvent, ignoreError} from "../../../util"; |
| import {keepSessionAliveAction} from "../actions"; |
| |
| @Injectable({providedIn: "root"}) |
| export class KeepAliveEffect { |
| |
| public keepAliveTimeInMs = 60000; |
| |
| public keepSessionAlive$ = createEffect(() => this.actions$.pipe( |
| ofType(keepSessionAliveAction), |
| switchMap(() => this.keepSessionAlive()) |
| ), {dispatch: false}); |
| |
| public constructor( |
| private readonly actions$: Actions, |
| private readonly authService: AuthService, |
| private readonly coreApiService: CoreApiService, |
| @Inject(DOCUMENT) private readonly document: Document |
| ) { |
| |
| } |
| |
| public keepSessionAlive(): Observable<any> { |
| const timer$ = timer(this.keepAliveTimeInMs); |
| const returnToApp$ = fromReturningToBrowserTabEvent(this.document); |
| |
| // The GET is called either after a specific amount of time or when the tab is refocused: |
| return race(timer$, returnToApp$).pipe( |
| // The session is kept alive only if there is a token: |
| switchMap(() => { |
| if (this.authService.token == null) { |
| return Promise.resolve(); |
| } |
| return this.coreApiService.keepAlive().pipe(); |
| }), |
| // All errors are ignored here: |
| ignoreError(), |
| endWith(0), |
| // This repeats the Observable as long as there is a token: |
| repeat(), |
| takeWhile(() => this.authService.token != null) |
| ); |
| } |
| |
| } |