1
1
import React from 'react' ;
2
2
3
- import { BrowserRouter as Router , Switch , Route , useHistory } from 'react-router-dom' ;
3
+ import { BrowserRouter as Router , Switch , Route , useHistory , Redirect } from 'react-router-dom' ;
4
4
5
- import Header , { AdminHeader } from "./components/Header" ;
5
+ import Header , { AdminHeader , LoginHeader } from "./components/Header" ;
6
6
7
+ import Login from './pages/Login/Login' ;
7
8
import HomePage from './pages/Home' ;
8
9
import Admin from './pages/Admin' ;
9
10
import Search360 from './pages/DataView360/Search/Search' ;
10
- import View360 from './pages/DataView360/View/View ' ;
11
+ import View360 from './pages/DataView360/View/View360 ' ;
11
12
import About from './pages/About' ;
12
- import Login from './components/Login/Login ' ;
13
+ import RefreshDlg from './components/RefreshDlg ' ;
13
14
import Check from './pages/Check/Check' ;
14
- import useToken from './components/Login/useToken' ;
15
- var jwt = require ( 'jsonwebtoken' ) ;
15
+ import Refresh from './components/Refresh' ;
16
16
17
+ import useToken from './pages/Login/useToken' ;
18
+
19
+ let jwt = require ( 'jsonwebtoken' ) ;
20
+
21
+ const REFRESH_POPUP_TIME = 300 // seconds
17
22
18
23
// Triggers token expiration check
19
24
const sleep = time => new Promise ( resolve => setTimeout ( resolve , time ) )
@@ -22,129 +27,149 @@ const expTimer = () => sleep(500).then(() => ({}))
22
27
const AuthContext = React . createContext ( )
23
28
24
29
function AuthProvider ( { children} ) {
25
- const [ state , setState ] = React . useState ( {
26
- status : 'pending' ,
27
- error : null ,
28
- user : null , } )
29
-
30
- React . useEffect ( ( ) => {
31
- expTimer ( ) . then (
32
- user => setState ( { status : 'success' , error : null , user} ) //
30
+ const [ state , setState ] = React . useState ( {
31
+ status : 'pending' ,
32
+ error : null ,
33
+ user : null ,
34
+ } )
35
+
36
+ React . useEffect ( ( ) => {
37
+ expTimer ( ) . then (
38
+ user => setState ( { status : 'success' , error : null , user} ) //
39
+ )
40
+ } , )
41
+
42
+ return (
43
+ < AuthContext . Provider value = { state } >
44
+ { state . status === 'pending' ? (
45
+ 'App ACP: Loading...'
46
+ ) : state . status === 'error' ? (
47
+ < div >
48
+ Oh no
49
+ < div >
50
+ < pre > { state . error . message } </ pre >
51
+ </ div >
52
+ </ div >
53
+ ) : (
54
+ children
55
+ ) }
56
+ </ AuthContext . Provider >
33
57
)
34
- } , )
35
-
36
- return (
37
- < AuthContext . Provider value = { state } >
38
- { state . status === 'pending' ? (
39
- 'App ACP: Loading...'
40
- ) : state . status === 'error' ? (
41
- < div >
42
- Oh no
43
- < div >
44
- < pre > { state . error . message } </ pre >
45
- </ div >
46
- </ div >
47
- ) : (
48
- children
49
- ) }
50
- </ AuthContext . Provider >
51
- )
52
58
}
53
59
54
60
function useAuthState ( ) {
55
- const state = React . useContext ( AuthContext )
56
- const isPending = state . status === 'pending'
57
- const isError = state . status === 'error'
58
- const isSuccess = state . status === 'success'
59
- const isAuthenticated = state . user && isSuccess
60
- return {
61
- ...state ,
62
- isPending,
63
- isError,
64
- isSuccess,
65
- isAuthenticated,
66
- }
61
+ const state = React . useContext ( AuthContext )
62
+ const isPending = state . status === 'pending'
63
+ const isError = state . status === 'error'
64
+ const isSuccess = state . status === 'success'
65
+ const isAuthenticated = state . user && isSuccess
66
+ return {
67
+ ...state ,
68
+ isPending,
69
+ isError,
70
+ isSuccess,
71
+ isAuthenticated,
72
+ }
67
73
}
68
74
69
75
70
76
function AuthenticatedApp ( ) {
71
77
72
- const { access_token, setToken } = useToken ( ) ;
78
+ const { access_token, setToken} = useToken ( ) ;
73
79
74
-
75
- var decoded = jwt . decode ( access_token , { complete : true } ) ;
80
+ let decoded = jwt . decode ( access_token , { complete : true } ) ;
76
81
77
82
const userRole = decoded ?. payload . role ;
78
- var expTime = decoded ?. payload . exp - Date . now ( ) / 1000 ;
83
+ let expTime = decoded ?. payload . exp - Date . now ( ) / 1000 ;
84
+ const jwtExpired = ! expTime || expTime <= 0
79
85
80
- const jwtExpired = expTime <= 0
86
+ const popRefreshAlert = expTime > 0 && expTime < REFRESH_POPUP_TIME ; // Time in secs to pop up refresh dialog
81
87
82
- const hdr = userRole === 'admin' ? < AdminHeader /> : < Header /> // If we're going to display a header, which one?
88
+ const hdr = userRole === 'admin' ? < AdminHeader /> : < Header /> // If we're going to display a header, which one?
83
89
84
90
const history = useHistory ( ) ;
85
91
86
- return (
87
- < >
92
+ return (
88
93
< Router >
89
94
90
- { ! jwtExpired && hdr ? hdr : '' /* Above-chosen header, or if logged out, no header */ }
91
-
92
- { /* If not logged in, show login screen */
93
- ( ! access_token | jwtExpired ) ? < Login setToken = { setToken } /> : < Switch >
94
-
95
- < Route exact path = "/" >
96
- < HomePage />
97
- </ Route >
98
-
95
+ { ! jwtExpired && hdr ? hdr : < LoginHeader /> /* Above-chosen header, or if logged out, no header */ }
96
+ { popRefreshAlert &&
97
+ < RefreshDlg shouldOpen = { true } setToken = { setToken } /> } { /* Pop up the refresh dialog */ }
99
98
100
- { /* If an admin, render Upload page */
101
- userRole === 'admin' &&
102
- < Route path = "/admin" >
103
- < Admin />
104
- </ Route >
105
- }
99
+ { jwtExpired &&
100
+ < RefreshDlg shouldOpen = { false } setToken = { setToken } /> } { /* Too late, expired: close the dialog */ }
106
101
107
102
108
- < Route path = "/about" >
109
- < About />
110
- </ Route >
111
-
112
- < Route path = "/360view/search" >
113
- < Search360 />
114
- </ Route >
115
-
116
- < Route path = "/360view/view" >
117
- < View360 />
118
- </ Route >
119
-
120
- < Route path = "/check" >
121
- < Check />
122
- </ Route >
123
- </ Switch >
103
+ { /* If not logged in, show login screen */
104
+ ( ! access_token | jwtExpired ) ?
105
+ < Switch >
106
+ < Route path = "/about" >
107
+ < About />
108
+ </ Route >
109
+ < Route >
110
+ < Login setToken = { setToken } />
111
+ </ Route >
112
+ </ Switch >
113
+
114
+ : < Switch >
115
+ < Route exact path = "/login" >
116
+ < Redirect to = "/" />
117
+ </ Route >
118
+ < Route exact path = "/" >
119
+ < HomePage access_token = { access_token } />
120
+ </ Route >
121
+ < Route path = "/about" >
122
+ < About />
123
+ </ Route >
124
+
125
+ { /* If an admin, render Upload page */
126
+ userRole === 'admin' &&
127
+ < Route path = "/admin" >
128
+ < Admin access_token = { access_token } />
129
+ </ Route >
130
+ }
131
+
132
+
133
+ < Route path = "/360view/search" >
134
+ < Search360 access_token = { access_token } />
135
+ </ Route >
136
+
137
+ < Route path = "/360view/view" >
138
+ < View360 access_token = { access_token } />
139
+ </ Route >
140
+
141
+ < Route path = "/check" >
142
+ < Check access_token = { access_token } />
143
+ </ Route >
144
+
145
+ < Route path = "/ref" >
146
+ < Refresh />
147
+ </ Route >
148
+
149
+ </ Switch >
124
150
}
125
151
126
152
</ Router >
127
- </ >
128
- )
153
+ )
129
154
}
130
155
131
156
132
157
function Home ( ) {
133
- const { user} = useAuthState ( )
134
- /*eslint no-unused-vars: ["warn", { "varsIgnorePattern": "access_token" }]*/
135
- const { access_token, setToken } = useToken ( ) ;
136
- return user ? < AuthenticatedApp /> : < Login setToken = { setToken } />
158
+ const { user} = useAuthState ( )
159
+ /*eslint no-unused-vars: ["warn", { "varsIgnorePattern": "access_token" }]*/
160
+ const { access_token, setToken} = useToken ( ) ;
161
+ return user ? < AuthenticatedApp /> : < Login setToken = { setToken } />
137
162
}
138
163
139
164
function App ( ) {
140
165
141
- return (
142
- < AuthProvider >
143
- < div >
144
- < Home />
145
- </ div >
146
- </ AuthProvider >
147
- )
166
+ return (
167
+ < AuthProvider >
168
+ < div >
169
+ < Home />
170
+ </ div >
171
+ </ AuthProvider >
172
+ )
148
173
}
149
174
150
- export default App
175
+ export default App
0 commit comments