Merge pull request #263 in TEA/mina-sidor-fa-web from feature/TV-892-inactivity-check to develop
Squashed commit of the following:
commit 0a6b323e5d8d94c18ebada2cdb47a6a48f0f32bd
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Fri Nov 12 14:20:21 2021 +0100
Changed variable name after PR
commit 1cb495e7db4365720c1276959d77bc1f6d460c6f
Merge: 2bfe34ac b5071fcf
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Fri Nov 12 14:18:11 2021 +0100
Merge branch 'develop' into feature/TV-892-inactivity-check
commit 2bfe34acc5eb5e2c6260624de7c0d0c9c5a1728b
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Fri Nov 12 13:45:31 2021 +0100
Added check on last activity after application close
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, HostListener, Inject } from '@angular/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
|
||||
import { APPLICATION_CLOSED_TIME_STAMP } from '@msfa-constants/local-storage-keys';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { AuthenticationService } from '@msfa-services/api/authentication.service';
|
||||
import { IdleService } from '@msfa-services/api/idle.service';
|
||||
@@ -18,6 +19,13 @@ export class AppComponent {
|
||||
userIsIdle$: Observable<boolean> = this.idleService.isIdle$;
|
||||
timeLeftBeforeLogout$: Observable<string> = this.idleService.timeLeftBeforeLogout$;
|
||||
|
||||
// Saving latest activity timestamp when application is closed
|
||||
// to avoid users be automatically logged in if user hasn't used the application for a while.
|
||||
@HostListener('window:beforeunload')
|
||||
saveApplicationClosedTimestamp(): void {
|
||||
localStorage.setItem(APPLICATION_CLOSED_TIME_STAMP, new Date().getTime().toString());
|
||||
}
|
||||
|
||||
constructor(
|
||||
@Inject(DOCUMENT) private document: Document,
|
||||
private router: Router,
|
||||
|
||||
@@ -2,10 +2,12 @@ export const AUTH_TOKEN_KEY = 'id_token';
|
||||
export const AUTH_TOKEN_EXPIRE_KEY = 'expires_at';
|
||||
export const AUTH_TOKEN_EXPIRES_IN_KEY = 'expires_in';
|
||||
export const SELECTED_ORGANIZATION_NUMBER_KEY = 'selected_orgnr';
|
||||
export const APPLICATION_CLOSED_TIME_STAMP = 'application_closed';
|
||||
|
||||
export const ALL_LOCAL_STORAGE_KEYS = [
|
||||
AUTH_TOKEN_KEY,
|
||||
AUTH_TOKEN_EXPIRE_KEY,
|
||||
AUTH_TOKEN_EXPIRES_IN_KEY,
|
||||
SELECTED_ORGANIZATION_NUMBER_KEY,
|
||||
APPLICATION_CLOSED_TIME_STAMP,
|
||||
];
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import {
|
||||
ALL_LOCAL_STORAGE_KEYS,
|
||||
APPLICATION_CLOSED_TIME_STAMP,
|
||||
AUTH_TOKEN_EXPIRES_IN_KEY,
|
||||
AUTH_TOKEN_EXPIRE_KEY,
|
||||
AUTH_TOKEN_KEY,
|
||||
@@ -10,7 +11,7 @@ import {
|
||||
import { environment } from '@msfa-environment';
|
||||
import { AuthenticationResponse } from '@msfa-models/api/authentication.response.model';
|
||||
import { Authentication, mapAuthApiResponseToAuthenticationResult } from '@msfa-models/authentication.model';
|
||||
import { add, isBefore, sub } from 'date-fns';
|
||||
import { add, isAfter, isBefore, sub } from 'date-fns';
|
||||
import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
|
||||
import { catchError, distinctUntilChanged, filter, map, tap } from 'rxjs/operators';
|
||||
|
||||
@@ -37,8 +38,19 @@ export class AuthenticationService {
|
||||
]).pipe(
|
||||
filter(([token, expiresAt]) => !!(token && expiresAt)),
|
||||
map(([, expiresAt]) => {
|
||||
const now = new Date();
|
||||
const applicationClosedTimeStamp = localStorage.getItem(APPLICATION_CLOSED_TIME_STAMP);
|
||||
// Checking to see if the user has been active on the page within the last hour
|
||||
const applicationClosedWithin1Hour =
|
||||
!applicationClosedTimeStamp || isAfter(+applicationClosedTimeStamp, sub(now, { hours: 1 }));
|
||||
const isValid = isBefore(now, sub(expiresAt, { minutes: 1 })) && applicationClosedWithin1Hour;
|
||||
|
||||
if (applicationClosedTimeStamp) {
|
||||
localStorage.removeItem(APPLICATION_CLOSED_TIME_STAMP);
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: isBefore(new Date(), sub(expiresAt, { minutes: 1 })),
|
||||
isValid,
|
||||
isRefreshable: false,
|
||||
// isRefreshable: isBefore(new Date(), expiresAt),
|
||||
};
|
||||
@@ -102,16 +114,18 @@ export class AuthenticationService {
|
||||
);
|
||||
}
|
||||
|
||||
private get _localStorageData(): { id_token: string; expires_at: number; expires_in: number } {
|
||||
const id_token = localStorage.getItem(AUTH_TOKEN_KEY);
|
||||
private get _localStorageData(): { idToken: string; expiresAt: number; expiresIn: number; lastActive: number } {
|
||||
const idToken = localStorage.getItem(AUTH_TOKEN_KEY);
|
||||
const expiresAt = localStorage.getItem(AUTH_TOKEN_EXPIRE_KEY);
|
||||
const expiresIn = localStorage.getItem(AUTH_TOKEN_EXPIRES_IN_KEY);
|
||||
const lastActive = localStorage.getItem(APPLICATION_CLOSED_TIME_STAMP);
|
||||
|
||||
return id_token && expiresAt && expiresIn
|
||||
return idToken && expiresAt && expiresIn
|
||||
? {
|
||||
id_token,
|
||||
expires_at: +JSON.parse(expiresAt),
|
||||
expires_in: +expiresIn,
|
||||
idToken,
|
||||
expiresAt: +expiresAt,
|
||||
expiresIn: +expiresIn,
|
||||
lastActive: +lastActive,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
@@ -130,9 +144,9 @@ export class AuthenticationService {
|
||||
const localStorageData = this._localStorageData;
|
||||
|
||||
if (localStorageData) {
|
||||
this._token$.next(localStorageData.id_token);
|
||||
this._expiresAt$.next(localStorageData.expires_at);
|
||||
this._expiresIn$.next(localStorageData.expires_in);
|
||||
this._token$.next(localStorageData.idToken);
|
||||
this._expiresAt$.next(localStorageData.expiresAt);
|
||||
this._expiresIn$.next(localStorageData.expiresIn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user