Guest User

Untitled

a guest
Jun 12th, 2020
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // App
  2.  
  3. class App extends Component {
  4.  
  5.  
  6.     render() {
  7.  
  8.         //...
  9.  
  10.         return (
  11.             <Fragment>
  12.                 <NotificationContainer />
  13.                 <IntlProvider
  14.                     locale={currentAppLocale.locale}
  15.                     messages={currentAppLocale.messages}
  16.                 >
  17.                     <Fragment>
  18.                         <Switch>
  19.  
  20.                             {/* First protected route */}
  21.                             <Route path={`${match.url}app`} component={MainProtectedRoute} />
  22.  
  23.  
  24.                             {/* --------------------------------------------------------- */}
  25.                             {/* Below are all unprotected routes */}
  26.                             {/* --------------------------------------------------------- */}
  27.  
  28.                             {/* Error page, unprotected route. */}
  29.                             <Route path={`/error`} component={error} />
  30.  
  31.                             {/* Callback for Auth0 */}
  32.                             <Route
  33.                                 path="/callback"
  34.                                 render={props => {
  35.                                     handleAuthentication(this.props);
  36.                                     return <Callback {...props} />;
  37.                                 }}
  38.                             />
  39.  
  40.                             <Redirect to="/error" />
  41.  
  42.                         </Switch>
  43.                     </Fragment>
  44.                 </IntlProvider>
  45.             </Fragment>
  46.         );
  47.     }
  48. }
  49.  
  50. // MainProtectedRoute
  51.  
  52.  
  53. class MainApp extends Component {
  54.  
  55.     constructor(props) {
  56.         super(props);
  57.     }
  58.  
  59.     async componentDidMount() {
  60.  
  61.         //======================================
  62.         //========== Authentication ============
  63.         //======================================
  64.  
  65.         // Auth checking
  66.  
  67.         await renewSession(this.props.dispatch);
  68.  
  69.     }
  70.  
  71.     render() {
  72.  
  73.         const { match, containerClassnames } = this.props;
  74.  
  75.  
  76.  
  77.  
  78.         if (this.props.auth.user === false) {
  79.             return (
  80.                 <div className="custom-spinner" >
  81.                     <div className="loading"></div>
  82.                 </div>
  83.             );
  84.         } else {
  85.  
  86.             // Here I check first allowed route for the user based on it permissions and redirect it there.
  87.             // ...
  88.  
  89.             return (
  90.  
  91.                 <div id="app-container" className={containerClassnames}>
  92.  
  93.                     <TopNav history={this.props.history} />
  94.                     <Sidebar />
  95.                     <main>
  96.                         <div className="container-fluid">
  97.  
  98.                             <Switch>
  99.  
  100.                                 <Route path={`${match.url}/some1`} component={some1} />
  101.                                 //...
  102.  
  103.                                 <Redirect to="/error" />
  104.  
  105.                             </Switch>
  106.                             <ColorSwitcher />
  107.                         </div>
  108.                     </main>
  109.                 </div>
  110.             );
  111.  
  112.  
  113.         };
  114.  
  115.  
  116.     }
  117. }
  118.  
  119. const mapStateToProps = (state) => {
  120.     const { containerClassnames } = state.menu;
  121.     return {
  122.         containerClassnames,
  123.         auth: state.auth,
  124.         loading: state.loading.loading
  125.     }
  126. };
  127.  
  128. export default withRouter(
  129.     connect(
  130.         mapStateToProps,
  131.  
  132.     )(MainApp)
  133. );
  134.  
  135.  
  136. // renewSession
  137.  
  138. /**
  139.  * Check if session is still active, renewal user's data from access_token
  140.  */
  141. export const renewSession = (dispatch = false) => {
  142.  
  143.  
  144.     // https://auth0.com/docs/api-auth/tutorials/silent-authentication#renew-expired-tokens
  145.     _auth0connection.checkSession({}, (err, authResult) => {
  146.  
  147.         if (authResult && authResult.accessToken && authResult.idToken) {
  148.  
  149.             // User still authenticated, as payload on Auth0 may be changed in real time, I rewrite payload data on each checking of auth
  150.             // to be able to react payload changes on the fly.
  151.             _setSession(authResult, dispatch);
  152.  
  153.  
  154.  
  155.         } else if (err) {
  156.  
  157.             // Needs to be authenticated
  158.             login();
  159.  
  160.         }
  161.  
  162.     });
  163.  
  164. }
  165.  
  166. // Below are helper functions for renewSession
  167.  
  168. const _auth0connection = new auth0.WebAuth({
  169.     domain: AUTH_CONFIG.domain,
  170.     clientID: AUTH_CONFIG.clientID,
  171.     redirectUri: AUTH_CONFIG.callbackUrl,
  172.     responseType: '...',
  173.     audience: `...`,
  174.     scope: '...'
  175. });
  176.  
  177. const _setSession = (authResult, dispatch, permissions = false) => {
  178.  
  179.     _setToState(authResult, dispatch);
  180.  
  181.     _scheduleRenewal(authResult.idTokenPayload.exp, dispatch);
  182.  
  183. }
  184.  
  185. import jwt_decode from 'jwt-decode';
  186. const _setToState = (authResult, dispatch) => {
  187.     const authInfo = {
  188.         clientId: authResult.idTokenPayload.sub,
  189.         expiresAt: authResult.expiresAt,
  190.         accessToken: authResult.accessToken,
  191.         state: authResult.state,
  192.         idTokenPayload: {
  193.             //...
  194.         },
  195.         permissions: jwt_decode(authResult.accessToken).permissions
  196.     };
  197.     dispatch(setAuthStore(authInfo));
  198. }
  199.  
  200. // setAuthStore at the end does (stores data from access_token to redux store):
  201.  
  202. case SET_AUTH_STORE:
  203. return {
  204.     ...state,
  205.     user: action.payload
  206. }
  207. break;
  208.  
  209. const _scheduleRenewal = (exp, dispatch) => {
  210.     let expiresAt = exp;
  211.     const timeout = expiresAt * 1000 - Date.now();
  212.  
  213.     if (timeout > 1) {
  214.  
  215.         const tokenRenewalTimeout = setTimeout(() => {
  216.             renewSession(dispatch);
  217.         }, timeout);
  218.         dispatch(setAuthTimer(tokenRenewalTimeout));
  219.  
  220.     }
  221. }
  222.  
  223. // setAuthTime does:
  224.  
  225. case SET_AUTH_TIMER:
  226. return {
  227.     ...state,
  228.     tokenRenewalTimeout: action.payload
  229. }
  230.  
  231. export const login = () => {
  232.     _auth0connection.authorize();
  233. }
Add Comment
Please, Sign In to add comment