github.com/minio/console@v1.4.1/web-app/src/ProtectedRoutes.tsx (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2021 MinIO, Inc.
     3  //
     4  // This program is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Affero General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // This program is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  // GNU Affero General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Affero General Public License
    15  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16  
    17  import { useEffect, useState } from "react";
    18  import { Navigate, useLocation } from "react-router-dom";
    19  import useApi from "./screens/Console/Common/Hooks/useApi";
    20  import { ErrorResponseHandler } from "./common/types";
    21  import { ReplicationSite } from "./screens/Console/Configurations/SiteReplication/SiteReplication";
    22  import { useSelector } from "react-redux";
    23  import { SRInfoStateType } from "./types";
    24  import { AppState, useAppDispatch } from "./store";
    25  import LoadingComponent from "./common/LoadingComponent";
    26  import { fetchSession } from "./screens/LoginPage/sessionThunk";
    27  import { setSiteReplicationInfo, setLocationPath } from "./systemSlice";
    28  import { SessionCallStates } from "./screens/Console/consoleSlice.types";
    29  
    30  interface ProtectedRouteProps {
    31    Component: any;
    32  }
    33  
    34  const ProtectedRoute = ({ Component }: ProtectedRouteProps) => {
    35    const dispatch = useAppDispatch();
    36  
    37    const userLoggedIn = useSelector((state: AppState) => state.system.loggedIn);
    38    const [componentLoading, setComponentLoading] = useState<boolean>(true);
    39    const sessionLoadingState = useSelector(
    40      (state: AppState) => state.console.sessionLoadingState,
    41    );
    42    const anonymousMode = useSelector(
    43      (state: AppState) => state.system.anonymousMode,
    44    );
    45    const { pathname = "" } = useLocation();
    46  
    47    const StorePathAndRedirect = () => {
    48      localStorage.setItem("redirect-path", pathname);
    49      return <Navigate to={{ pathname: `login` }} />;
    50    };
    51  
    52    useEffect(() => {
    53      dispatch(setLocationPath(pathname));
    54    }, [dispatch, pathname]);
    55  
    56    useEffect(() => {
    57      dispatch(fetchSession());
    58    }, [dispatch]);
    59  
    60    useEffect(() => {
    61      if (sessionLoadingState === SessionCallStates.Done) {
    62        setComponentLoading(false);
    63      }
    64    }, [dispatch, sessionLoadingState]);
    65  
    66    const [, invokeSRInfoApi] = useApi(
    67      (res: any) => {
    68        const { name: curSiteName, enabled = false } = res || {};
    69  
    70        let siteList = res.site;
    71        if (!siteList) {
    72          siteList = [];
    73        }
    74        const isSiteNameInList = siteList.find((si: ReplicationSite) => {
    75          return si.name === curSiteName;
    76        });
    77  
    78        const isCurSite = enabled && isSiteNameInList;
    79        const siteReplicationDetail: SRInfoStateType = {
    80          enabled: enabled,
    81          curSite: isCurSite,
    82          siteName: isCurSite ? curSiteName : "",
    83        };
    84  
    85        dispatch(setSiteReplicationInfo(siteReplicationDetail));
    86      },
    87      (err: ErrorResponseHandler) => {
    88        // we will fail this call silently, but show it on the console
    89        console.error(`Error loading site replication status`, err);
    90      },
    91    );
    92  
    93    useEffect(() => {
    94      if (userLoggedIn && !componentLoading && !anonymousMode) {
    95        invokeSRInfoApi("GET", `api/v1/admin/site-replication`);
    96      }
    97      // eslint-disable-next-line react-hooks/exhaustive-deps
    98    }, [userLoggedIn, componentLoading]);
    99  
   100    // if we're still trying to retrieve user session render nothing
   101    if (componentLoading) {
   102      return <LoadingComponent />;
   103    }
   104  
   105    // redirect user to the right page based on session status
   106    return userLoggedIn ? <Component /> : <StorePathAndRedirect />;
   107  };
   108  
   109  export default ProtectedRoute;