-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPrivateRoute.tsx
105 lines (89 loc) · 2.59 KB
/
PrivateRoute.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { Redirect, RedirectProps, Route, RouteProps } from 'react-router';
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { loginWithToken, selectIsAuthenticated } from '../features/authentication/authenticationSlice';
import Cookies from 'js-cookie';
import { HatClientService } from '../services/HatClientService';
import * as queryString from 'query-string';
interface OwnProps extends RouteProps {
newAuth?: boolean;
}
type Query = {
token?: string;
repeat?: string;
email?: string;
application_id?: string;
redirect_uri?: string;
};
export function PrivateRoute({ children, ...rest }: OwnProps) {
const isAuthenticated = useSelector(selectIsAuthenticated);
// TODO Add the type to the state useState<Query>
const [query, setQuery] = useState({});
const dispatch = useDispatch();
useEffect(() => {
const tokenStored = Cookies.get('token') || sessionStorage.getItem('token');
const { token, repeat, email, application_id, redirect_uri } = queryString.parse(window.location.search) as Query;
setQuery({
repeat: repeat === 'true',
email: email,
applicationId: application_id,
redirectUri: redirect_uri,
});
const hatSvc = HatClientService.getInstance();
if (token && !hatSvc.isTokenExpired(token)) {
dispatch(loginWithToken(token));
HatClientService.getInstance(token);
} else if (tokenStored && !hatSvc.isTokenExpired(tokenStored)) {
dispatch(loginWithToken(tokenStored));
HatClientService.getInstance(tokenStored);
}
}, [dispatch]);
return (
<Route
{...rest}
render={({ location }) =>
isAuthenticated ? (
children
) : (
<DelayedRedirect
to={{
pathname: '/auth/login',
state: { from: location, query: query },
}}
delay={100}
/>
)
}
/>
);
}
interface DelayedProps {
delay: number;
}
interface DelayedState {
timeToRedirect: boolean;
}
class DelayedRedirect extends React.Component<RedirectProps & DelayedProps, DelayedState> {
timeout: any = null;
state: DelayedState = {
timeToRedirect: false,
};
componentDidMount() {
this.timeout = setTimeout(() => {
this.setState({
timeToRedirect: true,
});
}, this.props.delay);
}
componentWillUnmount() {
clearTimeout(this.timeout);
}
render() {
const { ...props } = this.props;
const { timeToRedirect } = this.state;
if (timeToRedirect) {
return <Redirect {...props} />;
}
return null;
}
}