@@ -3,7 +3,7 @@ import { Router } from 'react-router';
3
3
import { bindActionCreators } from 'redux' ;
4
4
import { StyleSheetManager } from 'styled-components' ;
5
5
6
- import { hasExpired } from '../shared/account-expiry' ;
6
+ import { closeToExpiry , hasExpired } from '../shared/account-expiry' ;
7
7
import { ILinuxSplitTunnelingApplication , IWindowsApplication } from '../shared/application-types' ;
8
8
import {
9
9
AccessMethodSetting ,
@@ -103,9 +103,11 @@ export default class AppRenderer {
103
103
private deviceState ?: DeviceState ;
104
104
private loginState : LoginState = 'none' ;
105
105
private previousLoginState : LoginState = 'none' ;
106
- private loginScheduler = new Scheduler ( ) ;
107
106
private connectedToDaemon = false ;
108
107
108
+ private loginScheduler = new Scheduler ( ) ;
109
+ private expiryScheduler = new Scheduler ( ) ;
110
+
109
111
constructor ( ) {
110
112
log . addOutput ( new ConsoleOutput ( LogLevel . debug ) ) ;
111
113
log . addOutput ( new IpcOutput ( LogLevel . debug ) ) ;
@@ -669,14 +671,18 @@ export default class AppRenderer {
669
671
this . resetNavigation ( ) ;
670
672
}
671
673
672
- private resetNavigation ( ) {
674
+ private resetNavigation ( replaceRoot ?: boolean ) {
673
675
if ( this . history ) {
674
676
const pathname = this . history . location . pathname as RoutePath ;
675
677
const nextPath = this . getNavigationBase ( ) as RoutePath ;
676
678
677
679
if ( pathname !== nextPath ) {
678
680
const transition = this . getNavigationTransition ( pathname , nextPath ) ;
679
- this . history . reset ( nextPath , { transition } ) ;
681
+ if ( replaceRoot ) {
682
+ this . history . replaceRoot ( nextPath , { transition } ) ;
683
+ } else {
684
+ this . history . reset ( nextPath , { transition } ) ;
685
+ }
680
686
}
681
687
}
682
688
}
@@ -933,23 +939,39 @@ export default class AppRenderer {
933
939
934
940
const state = this . reduxStore . getState ( ) ;
935
941
const previousExpiry = state . account . expiry ;
942
+
943
+ this . expiryScheduler . cancel ( ) ;
944
+
945
+ if ( expiry !== undefined ) {
946
+ const expired = hasExpired ( expiry ) ;
947
+
948
+ // Set state to expired when expiry date passes.
949
+ if ( ! expired && closeToExpiry ( expiry ) ) {
950
+ const delay = new Date ( expiry ) . getTime ( ) - Date . now ( ) ;
951
+ this . expiryScheduler . schedule ( ( ) => this . handleExpiry ( expiry , true ) , delay ) ;
952
+ }
953
+
954
+ if ( expiry !== previousExpiry ) {
955
+ this . handleExpiry ( expiry , expired ) ;
956
+ }
957
+ } else {
958
+ this . handleExpiry ( expiry ) ;
959
+ }
960
+ }
961
+
962
+ private handleExpiry ( expiry ?: string , expired ?: boolean ) {
963
+ const state = this . reduxStore . getState ( ) ;
936
964
this . reduxActions . account . updateAccountExpiry ( expiry ) ;
937
965
938
- const expired = expiry !== undefined && hasExpired ( expiry ) ;
939
966
if (
940
- this . history &&
941
- state . account . status . type === 'ok' &&
942
967
expiry !== undefined &&
943
- expiry !== previousExpiry &&
968
+ state . account . status . type === 'ok' &&
944
969
( ( state . account . status . expiredState === undefined && expired ) ||
945
970
( state . account . status . expiredState === 'expired' && ! expired ) ) &&
946
971
// If the login navigation is already scheduled no navigation is needed
947
972
! this . loginScheduler . isRunning
948
973
) {
949
- const prevPath = this . history . location . pathname as RoutePath ;
950
- const nextPath = expired ? RoutePath . expired : RoutePath . timeAdded ;
951
- const transition = this . getNavigationTransition ( prevPath , nextPath ) ;
952
- this . history . replaceRoot ( nextPath , { transition } ) ;
974
+ this . resetNavigation ( true ) ;
953
975
}
954
976
}
955
977
0 commit comments