build(deps): update dependency react-router-dom to v6 (#2565)

* build(deps): update dependency react-router-dom to v6

* fix(web): update code to conform to react-router 6 convention

* refactor(web): react-router -> react-router-dom

* refactor(web): make 2fa consts relative

* refactor(web): rename 2fa consts for clarity

Co-authored-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: Amir Zarrinkafsh <nightah@me.com>
pull/2529/head^2
renovate[bot] 2021-11-05 13:36:52 +11:00 committed by GitHub
parent c8cddf4f16
commit eae353e315
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 527 additions and 609 deletions

View File

@ -19,8 +19,7 @@
"react-ga": "3.3.0", "react-ga": "3.3.0",
"react-loading": "2.0.3", "react-loading": "2.0.3",
"react-otp-input": "2.4.0", "react-otp-input": "2.4.0",
"react-router": "5.2.1", "react-router-dom": "6.0.0",
"react-router-dom": "5.3.0",
"u2f-api": "1.2.1" "u2f-api": "1.2.1"
}, },
"scripts": { "scripts": {
@ -127,7 +126,6 @@
"@types/qrcode.react": "1.0.2", "@types/qrcode.react": "1.0.2",
"@types/react": "17.0.34", "@types/react": "17.0.34",
"@types/react-dom": "17.0.11", "@types/react-dom": "17.0.11",
"@types/react-router-dom": "5.3.2",
"@typescript-eslint/eslint-plugin": "5.3.0", "@typescript-eslint/eslint-plugin": "5.3.0",
"@typescript-eslint/parser": "5.3.0", "@typescript-eslint/parser": "5.3.0",
"@vitejs/plugin-react": "1.0.7", "@vitejs/plugin-react": "1.0.7",

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import { config as faConfig } from "@fortawesome/fontawesome-svg-core"; import { config as faConfig } from "@fortawesome/fontawesome-svg-core";
import { CssBaseline, ThemeProvider } from "@material-ui/core"; import { CssBaseline, ThemeProvider } from "@material-ui/core";
import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom"; import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import NotificationBar from "@components/NotificationBar"; import NotificationBar from "@components/NotificationBar";
import { import {
@ -64,32 +64,18 @@ const App: React.FC = () => {
<NotificationsContext.Provider value={{ notification, setNotification }}> <NotificationsContext.Provider value={{ notification, setNotification }}>
<Router basename={getBasePath()}> <Router basename={getBasePath()}>
<NotificationBar onClose={() => setNotification(null)} /> <NotificationBar onClose={() => setNotification(null)} />
<Switch> <Routes>
<Route path={ResetPasswordStep1Route} exact> <Route path={ResetPasswordStep1Route} element={<ResetPasswordStep1 />} />
<ResetPasswordStep1 /> <Route path={ResetPasswordStep2Route} element={<ResetPasswordStep2 />} />
</Route> <Route path={RegisterSecurityKeyRoute} element={<RegisterSecurityKey />} />
<Route path={ResetPasswordStep2Route} exact> <Route path={RegisterOneTimePasswordRoute} element={<RegisterOneTimePassword />} />
<ResetPasswordStep2 /> <Route path={LogoutRoute} element={<SignOut />} />
</Route> <Route path={ConsentRoute} element={<ConsentView />} />
<Route path={RegisterSecurityKeyRoute} exact> <Route
<RegisterSecurityKey /> path={`${FirstFactorRoute}*`}
</Route> element={<LoginPortal rememberMe={getRememberMe()} resetPassword={getResetPassword()} />}
<Route path={RegisterOneTimePasswordRoute} exact> />
<RegisterOneTimePassword /> </Routes>
</Route>
<Route path={LogoutRoute} exact>
<SignOut />
</Route>
<Route path={ConsentRoute} exact>
<ConsentView />
</Route>
<Route path={FirstFactorRoute}>
<LoginPortal rememberMe={getRememberMe()} resetPassword={getResetPassword()} />
</Route>
<Route path="/">
<Redirect to={FirstFactorRoute} />
</Route>
</Switch>
</Router> </Router>
</NotificationsContext.Provider> </NotificationsContext.Provider>
</ThemeProvider> </ThemeProvider>

View File

@ -2,10 +2,10 @@ export const FirstFactorRoute: string = "/";
export const AuthenticatedRoute: string = "/authenticated"; export const AuthenticatedRoute: string = "/authenticated";
export const ConsentRoute: string = "/consent"; export const ConsentRoute: string = "/consent";
export const SecondFactorRoute: string = "/2fa"; export const SecondFactorRoute: string = "/2fa/";
export const SecondFactorU2FRoute: string = "/2fa/security-key"; export const SecondFactorU2FSubRoute: string = "security-key";
export const SecondFactorTOTPRoute: string = "/2fa/one-time-password"; export const SecondFactorTOTPSubRoute: string = "one-time-password";
export const SecondFactorPushRoute: string = "/2fa/push-notification"; export const SecondFactorPushSubRoute: string = "push-notification";
export const ResetPasswordStep1Route: string = "/reset-password/step1"; export const ResetPasswordStep1Route: string = "/reset-password/step1";
export const ResetPasswordStep2Route: string = "/reset-password/step2"; export const ResetPasswordStep2Route: string = "/reset-password/step2";

View File

@ -1,5 +1,5 @@
import queryString from "query-string"; import queryString from "query-string";
import { useLocation } from "react-router"; import { useLocation } from "react-router-dom";
export function useRedirectionURL() { export function useRedirectionURL() {
const location = useLocation(); const location = useLocation();

View File

@ -1,5 +1,5 @@
import queryString from "query-string"; import queryString from "query-string";
import { useLocation } from "react-router"; import { useLocation } from "react-router-dom";
export function useRequestMethod() { export function useRequestMethod() {
const location = useLocation(); const location = useLocation();

View File

@ -6,7 +6,7 @@ import { makeStyles, Typography, Button, IconButton, Link, CircularProgress, Tex
import { red } from "@material-ui/core/colors"; import { red } from "@material-ui/core/colors";
import classnames from "classnames"; import classnames from "classnames";
import QRCode from "qrcode.react"; import QRCode from "qrcode.react";
import { useHistory, useLocation } from "react-router"; import { useLocation, useNavigate } from "react-router-dom";
import AppStoreBadges from "@components/AppStoreBadges"; import AppStoreBadges from "@components/AppStoreBadges";
import { GoogleAuthenticator } from "@constants/constants"; import { GoogleAuthenticator } from "@constants/constants";
@ -18,7 +18,7 @@ import { extractIdentityToken } from "@utils/IdentityToken";
const RegisterOneTimePassword = function () { const RegisterOneTimePassword = function () {
const style = useStyles(); const style = useStyles();
const history = useHistory(); const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
// The secret retrieved from the API is all is ok. // The secret retrieved from the API is all is ok.
const [secretURL, setSecretURL] = useState("empty"); const [secretURL, setSecretURL] = useState("empty");
@ -32,7 +32,7 @@ const RegisterOneTimePassword = function () {
const processToken = extractIdentityToken(location.search); const processToken = extractIdentityToken(location.search);
const handleDoneClick = () => { const handleDoneClick = () => {
history.push(FirstFactorRoute); navigate(FirstFactorRoute);
}; };
const completeRegistrationProcess = useCallback(async () => { const completeRegistrationProcess = useCallback(async () => {

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from "react"; import React, { useState, useEffect, useCallback } from "react";
import { makeStyles, Typography, Button } from "@material-ui/core"; import { makeStyles, Typography, Button } from "@material-ui/core";
import { useHistory, useLocation } from "react-router"; import { useLocation, useNavigate } from "react-router-dom";
import u2fApi from "u2f-api"; import u2fApi from "u2f-api";
import FingerTouchIcon from "@components/FingerTouchIcon"; import FingerTouchIcon from "@components/FingerTouchIcon";
@ -13,7 +13,7 @@ import { extractIdentityToken } from "@utils/IdentityToken";
const RegisterSecurityKey = function () { const RegisterSecurityKey = function () {
const style = useStyles(); const style = useStyles();
const history = useHistory(); const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
const { createErrorNotification } = useNotifications(); const { createErrorNotification } = useNotifications();
const [, setRegistrationInProgress] = useState(false); const [, setRegistrationInProgress] = useState(false);
@ -21,7 +21,7 @@ const RegisterSecurityKey = function () {
const processToken = extractIdentityToken(location.search); const processToken = extractIdentityToken(location.search);
const handleBackClick = () => { const handleBackClick = () => {
history.push(FirstFactorPath); navigate(FirstFactorPath);
}; };
const registerStep1 = useCallback(async () => { const registerStep1 = useCallback(async () => {
@ -43,14 +43,14 @@ const RegisterSecurityKey = function () {
const registerResponse = await u2fApi.register(registerRequests, [], 60); const registerResponse = await u2fApi.register(registerRequests, [], 60);
await completeU2FRegistrationProcessStep2(registerResponse); await completeU2FRegistrationProcessStep2(registerResponse);
setRegistrationInProgress(false); setRegistrationInProgress(false);
history.push(FirstFactorPath); navigate(FirstFactorPath);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
createErrorNotification( createErrorNotification(
"Failed to register your security key. The identity verification process might have timed out.", "Failed to register your security key. The identity verification process might have timed out.",
); );
} }
}, [processToken, createErrorNotification, history]); }, [processToken, createErrorNotification, navigate]);
useEffect(() => { useEffect(() => {
registerStep1(); registerStep1();

View File

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import { Grid, makeStyles, Button } from "@material-ui/core"; import { Grid, makeStyles, Button } from "@material-ui/core";
import { useHistory } from "react-router"; import { useNavigate } from "react-router-dom";
import { LogoutRoute as SignOutRoute } from "@constants/Routes"; import { LogoutRoute as SignOutRoute } from "@constants/Routes";
import LoginLayout from "@layouts/LoginLayout"; import LoginLayout from "@layouts/LoginLayout";
@ -13,10 +13,10 @@ export interface Props {
const AuthenticatedView = function (props: Props) { const AuthenticatedView = function (props: Props) {
const style = useStyles(); const style = useStyles();
const history = useHistory(); const navigate = useNavigate();
const handleLogoutClick = () => { const handleLogoutClick = () => {
history.push(SignOutRoute); navigate(SignOutRoute);
}; };
return ( return (

View File

@ -2,8 +2,9 @@ import React, { useEffect, Fragment, ReactNode } from "react";
import { Button, Grid, List, ListItem, ListItemIcon, ListItemText, Tooltip, makeStyles } from "@material-ui/core"; import { Button, Grid, List, ListItem, ListItemIcon, ListItemText, Tooltip, makeStyles } from "@material-ui/core";
import { AccountBox, CheckBox, Contacts, Drafts, Group } from "@material-ui/icons"; import { AccountBox, CheckBox, Contacts, Drafts, Group } from "@material-ui/icons";
import { useHistory } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { FirstFactorRoute } from "@constants/Routes";
import { useRequestedScopes } from "@hooks/Consent"; import { useRequestedScopes } from "@hooks/Consent";
import { useNotifications } from "@hooks/NotificationsContext"; import { useNotifications } from "@hooks/NotificationsContext";
import { useRedirector } from "@hooks/Redirector"; import { useRedirector } from "@hooks/Redirector";
@ -30,17 +31,17 @@ function showListItemAvatar(id: string) {
const ConsentView = function (props: Props) { const ConsentView = function (props: Props) {
const classes = useStyles(); const classes = useStyles();
const history = useHistory(); const navigate = useNavigate();
const redirect = useRedirector(); const redirect = useRedirector();
const { createErrorNotification, resetNotification } = useNotifications(); const { createErrorNotification, resetNotification } = useNotifications();
const [resp, fetch, , err] = useRequestedScopes(); const [resp, fetch, , err] = useRequestedScopes();
useEffect(() => { useEffect(() => {
if (err) { if (err) {
history.replace("/"); navigate(FirstFactorRoute);
console.error(`Unable to display consent screen: ${err.message}`); console.error(`Unable to display consent screen: ${err.message}`);
} }
}, [history, resetNotification, createErrorNotification, err]); }, [navigate, resetNotification, createErrorNotification, err]);
useEffect(() => { useEffect(() => {
fetch(); fetch();

View File

@ -2,7 +2,7 @@ import React, { MutableRefObject, useEffect, useRef, useState } from "react";
import { makeStyles, Grid, Button, FormControlLabel, Checkbox, Link } from "@material-ui/core"; import { makeStyles, Grid, Button, FormControlLabel, Checkbox, Link } from "@material-ui/core";
import classnames from "classnames"; import classnames from "classnames";
import { useHistory } from "react-router"; import { useNavigate } from "react-router-dom";
import FixedTextField from "@components/FixedTextField"; import FixedTextField from "@components/FixedTextField";
import { ResetPasswordStep1Route } from "@constants/Routes"; import { ResetPasswordStep1Route } from "@constants/Routes";
@ -24,7 +24,7 @@ export interface Props {
const FirstFactorForm = function (props: Props) { const FirstFactorForm = function (props: Props) {
const style = useStyles(); const style = useStyles();
const history = useHistory(); const navigate = useNavigate();
const redirectionURL = useRedirectionURL(); const redirectionURL = useRedirectionURL();
const requestMethod = useRequestMethod(); const requestMethod = useRequestMethod();
@ -74,7 +74,7 @@ const FirstFactorForm = function (props: Props) {
}; };
const handleResetPasswordClick = () => { const handleResetPasswordClick = () => {
history.push(ResetPasswordStep1Route); navigate(ResetPasswordStep1Route);
}; };
return ( return (

View File

@ -1,14 +1,14 @@
import React, { Fragment, ReactNode, useCallback, useEffect, useState } from "react"; import React, { Fragment, ReactNode, useCallback, useEffect, useState } from "react";
import { Redirect, Route, Switch, useHistory, useLocation } from "react-router"; import { Route, Routes, useLocation, useNavigate } from "react-router-dom";
import { import {
AuthenticatedRoute, AuthenticatedRoute,
FirstFactorRoute, FirstFactorRoute,
SecondFactorPushRoute, SecondFactorPushSubRoute,
SecondFactorRoute, SecondFactorRoute,
SecondFactorTOTPRoute, SecondFactorTOTPSubRoute,
SecondFactorU2FRoute, SecondFactorU2FSubRoute,
} from "@constants/Routes"; } from "@constants/Routes";
import { useConfiguration } from "@hooks/Configuration"; import { useConfiguration } from "@hooks/Configuration";
import { useNotifications } from "@hooks/NotificationsContext"; import { useNotifications } from "@hooks/NotificationsContext";
@ -34,7 +34,7 @@ const RedirectionErrorMessage =
"Redirection was determined to be unsafe and aborted. Ensure the redirection URL is correct."; "Redirection was determined to be unsafe and aborted. Ensure the redirection URL is correct.";
const LoginPortal = function (props: Props) { const LoginPortal = function (props: Props) {
const history = useHistory(); const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
const redirectionURL = useRedirectionURL(); const redirectionURL = useRedirectionURL();
const requestMethod = useRequestMethod(); const requestMethod = useRequestMethod();
@ -46,7 +46,7 @@ const LoginPortal = function (props: Props) {
const [userInfo, fetchUserInfo, , fetchUserInfoError] = userUserInfo(); const [userInfo, fetchUserInfo, , fetchUserInfoError] = userUserInfo();
const [configuration, fetchConfiguration, , fetchConfigurationError] = useConfiguration(); const [configuration, fetchConfiguration, , fetchConfigurationError] = useConfiguration();
const redirect = useCallback((url: string) => history.push(url), [history]); const redirect = useCallback((url: string) => navigate(url), [navigate]);
// Fetch the state when portal is mounted. // Fetch the state when portal is mounted.
useEffect(() => { useEffect(() => {
@ -128,11 +128,11 @@ const LoginPortal = function (props: Props) {
redirect(AuthenticatedRoute); redirect(AuthenticatedRoute);
} else { } else {
if (userInfo.method === SecondFactorMethod.U2F) { if (userInfo.method === SecondFactorMethod.U2F) {
redirect(`${SecondFactorU2FRoute}${redirectionSuffix}`); redirect(`${SecondFactorRoute}${SecondFactorU2FSubRoute}${redirectionSuffix}`);
} else if (userInfo.method === SecondFactorMethod.MobilePush) { } else if (userInfo.method === SecondFactorMethod.MobilePush) {
redirect(`${SecondFactorPushRoute}${redirectionSuffix}`); redirect(`${SecondFactorRoute}${SecondFactorPushSubRoute}${redirectionSuffix}`);
} else { } else {
redirect(`${SecondFactorTOTPRoute}${redirectionSuffix}`); redirect(`${SecondFactorRoute}${SecondFactorTOTPSubRoute}${redirectionSuffix}`);
} }
} }
} }
@ -165,38 +165,41 @@ const LoginPortal = function (props: Props) {
location.pathname === FirstFactorRoute; location.pathname === FirstFactorRoute;
return ( return (
<Switch> <Routes>
<Route path={FirstFactorRoute} exact> <Route
<ComponentOrLoading ready={firstFactorReady}> path={FirstFactorRoute}
<FirstFactorForm element={
disabled={firstFactorDisabled} <ComponentOrLoading ready={firstFactorReady}>
rememberMe={props.rememberMe} <FirstFactorForm
resetPassword={props.resetPassword} disabled={firstFactorDisabled}
onAuthenticationStart={() => setFirstFactorDisabled(true)} rememberMe={props.rememberMe}
onAuthenticationFailure={() => setFirstFactorDisabled(false)} resetPassword={props.resetPassword}
onAuthenticationSuccess={handleAuthSuccess} onAuthenticationStart={() => setFirstFactorDisabled(true)}
/> onAuthenticationFailure={() => setFirstFactorDisabled(false)}
</ComponentOrLoading> onAuthenticationSuccess={handleAuthSuccess}
</Route> />
<Route path={SecondFactorRoute}> </ComponentOrLoading>
{state && userInfo && configuration ? ( }
<SecondFactorForm />
authenticationLevel={state.authentication_level} <Route
userInfo={userInfo} path={`${SecondFactorRoute}*`}
configuration={configuration} element={
onMethodChanged={() => fetchUserInfo()} state && userInfo && configuration ? (
onAuthenticationSuccess={handleAuthSuccess} <SecondFactorForm
/> authenticationLevel={state.authentication_level}
) : null} userInfo={userInfo}
</Route> configuration={configuration}
<Route path={AuthenticatedRoute} exact> onMethodChanged={() => fetchUserInfo()}
{userInfo ? <AuthenticatedView name={userInfo.display_name} /> : null} onAuthenticationSuccess={handleAuthSuccess}
</Route> />
{/* By default we route to first factor page */} ) : null
<Route path="/"> }
<Redirect to={FirstFactorRoute} /> />
</Route> <Route
</Switch> path={AuthenticatedRoute}
element={userInfo ? <AuthenticatedView name={userInfo.display_name} /> : null}
/>
</Routes>
); );
}; };

View File

@ -1,15 +1,14 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { Grid, makeStyles, Button } from "@material-ui/core"; import { Grid, makeStyles, Button } from "@material-ui/core";
import { useHistory, Switch, Route, Redirect } from "react-router"; import { Route, Routes, useNavigate } from "react-router-dom";
import u2fApi from "u2f-api"; import u2fApi from "u2f-api";
import { import {
LogoutRoute as SignOutRoute, LogoutRoute as SignOutRoute,
SecondFactorTOTPRoute, SecondFactorPushSubRoute,
SecondFactorPushRoute, SecondFactorTOTPSubRoute,
SecondFactorU2FRoute, SecondFactorU2FSubRoute,
SecondFactorRoute,
} from "@constants/Routes"; } from "@constants/Routes";
import { useNotifications } from "@hooks/NotificationsContext"; import { useNotifications } from "@hooks/NotificationsContext";
import LoginLayout from "@layouts/LoginLayout"; import LoginLayout from "@layouts/LoginLayout";
@ -38,7 +37,7 @@ export interface Props {
const SecondFactorForm = function (props: Props) { const SecondFactorForm = function (props: Props) {
const style = useStyles(); const style = useStyles();
const history = useHistory(); const navigate = useNavigate();
const [methodSelectionOpen, setMethodSelectionOpen] = useState(false); const [methodSelectionOpen, setMethodSelectionOpen] = useState(false);
const { createInfoNotification, createErrorNotification } = useNotifications(); const { createInfoNotification, createErrorNotification } = useNotifications();
const [registrationInProgress, setRegistrationInProgress] = useState(false); const [registrationInProgress, setRegistrationInProgress] = useState(false);
@ -85,7 +84,7 @@ const SecondFactorForm = function (props: Props) {
}; };
const handleLogoutClick = () => { const handleLogoutClick = () => {
history.push(SignOutRoute); navigate(SignOutRoute);
}; };
return ( return (
@ -108,42 +107,48 @@ const SecondFactorForm = function (props: Props) {
</Button> </Button>
</Grid> </Grid>
<Grid item xs={12} className={style.methodContainer}> <Grid item xs={12} className={style.methodContainer}>
<Switch> <Routes>
<Route path={SecondFactorTOTPRoute} exact> <Route
<OneTimePasswordMethod path={SecondFactorTOTPSubRoute}
id="one-time-password-method" element={
authenticationLevel={props.authenticationLevel} <OneTimePasswordMethod
// Whether the user has a TOTP secret registered already id="one-time-password-method"
registered={props.userInfo.has_totp} authenticationLevel={props.authenticationLevel}
totp_period={props.configuration.totp_period} // Whether the user has a TOTP secret registered already
onRegisterClick={initiateRegistration(initiateTOTPRegistrationProcess)} registered={props.userInfo.has_totp}
onSignInError={(err) => createErrorNotification(err.message)} totp_period={props.configuration.totp_period}
onSignInSuccess={props.onAuthenticationSuccess} onRegisterClick={initiateRegistration(initiateTOTPRegistrationProcess)}
/> onSignInError={(err) => createErrorNotification(err.message)}
</Route> onSignInSuccess={props.onAuthenticationSuccess}
<Route path={SecondFactorU2FRoute} exact> />
<SecurityKeyMethod }
id="security-key-method" />
authenticationLevel={props.authenticationLevel} <Route
// Whether the user has a U2F device registered already path={SecondFactorU2FSubRoute}
registered={props.userInfo.has_u2f} element={
onRegisterClick={initiateRegistration(initiateU2FRegistrationProcess)} <SecurityKeyMethod
onSignInError={(err) => createErrorNotification(err.message)} id="security-key-method"
onSignInSuccess={props.onAuthenticationSuccess} authenticationLevel={props.authenticationLevel}
/> // Whether the user has a U2F device registered already
</Route> registered={props.userInfo.has_u2f}
<Route path={SecondFactorPushRoute} exact> onRegisterClick={initiateRegistration(initiateU2FRegistrationProcess)}
<PushNotificationMethod onSignInError={(err) => createErrorNotification(err.message)}
id="push-notification-method" onSignInSuccess={props.onAuthenticationSuccess}
authenticationLevel={props.authenticationLevel} />
onSignInError={(err) => createErrorNotification(err.message)} }
onSignInSuccess={props.onAuthenticationSuccess} />
/> <Route
</Route> path={SecondFactorPushSubRoute}
<Route path={SecondFactorRoute}> element={
<Redirect to={SecondFactorTOTPRoute} /> <PushNotificationMethod
</Route> id="push-notification-method"
</Switch> authenticationLevel={props.authenticationLevel}
onSignInError={(err) => createErrorNotification(err.message)}
onSignInSuccess={props.onAuthenticationSuccess}
/>
}
/>
</Routes>
</Grid> </Grid>
</Grid> </Grid>
</LoginLayout> </LoginLayout>

View File

@ -1,7 +1,7 @@
import React, { useEffect, useCallback, useState } from "react"; import React, { useEffect, useCallback, useState } from "react";
import { Typography, makeStyles } from "@material-ui/core"; import { Typography, makeStyles } from "@material-ui/core";
import { Redirect } from "react-router"; import { Navigate } from "react-router-dom";
import { FirstFactorRoute } from "@constants/Routes"; import { FirstFactorRoute } from "@constants/Routes";
import { useIsMountedRef } from "@hooks/Mounted"; import { useIsMountedRef } from "@hooks/Mounted";
@ -48,7 +48,7 @@ const SignOut = function (props: Props) {
if (redirectionURL && safeRedirect) { if (redirectionURL && safeRedirect) {
redirector(redirectionURL); redirector(redirectionURL);
} else { } else {
return <Redirect to={FirstFactorRoute} />; return <Navigate to={FirstFactorRoute} />;
} }
} }

View File

@ -1,7 +1,7 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { Grid, Button, makeStyles } from "@material-ui/core"; import { Grid, Button, makeStyles } from "@material-ui/core";
import { useHistory } from "react-router"; import { useNavigate } from "react-router-dom";
import FixedTextField from "@components/FixedTextField"; import FixedTextField from "@components/FixedTextField";
import { FirstFactorRoute } from "@constants/Routes"; import { FirstFactorRoute } from "@constants/Routes";
@ -14,7 +14,7 @@ const ResetPasswordStep1 = function () {
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [error, setError] = useState(false); const [error, setError] = useState(false);
const { createInfoNotification, createErrorNotification } = useNotifications(); const { createInfoNotification, createErrorNotification } = useNotifications();
const history = useHistory(); const navigate = useNavigate();
const doInitiateResetPasswordProcess = async () => { const doInitiateResetPasswordProcess = async () => {
if (username === "") { if (username === "") {
@ -35,7 +35,7 @@ const ResetPasswordStep1 = function () {
}; };
const handleCancelClick = () => { const handleCancelClick = () => {
history.push(FirstFactorRoute); navigate(FirstFactorRoute);
}; };
return ( return (

View File

@ -2,7 +2,7 @@ import React, { useState, useCallback, useEffect } from "react";
import { Grid, Button, makeStyles } from "@material-ui/core"; import { Grid, Button, makeStyles } from "@material-ui/core";
import classnames from "classnames"; import classnames from "classnames";
import { useHistory, useLocation } from "react-router"; import { useLocation, useNavigate } from "react-router-dom";
import FixedTextField from "@components/FixedTextField"; import FixedTextField from "@components/FixedTextField";
import { FirstFactorRoute } from "@constants/Routes"; import { FirstFactorRoute } from "@constants/Routes";
@ -20,7 +20,7 @@ const ResetPasswordStep2 = function () {
const [errorPassword1, setErrorPassword1] = useState(false); const [errorPassword1, setErrorPassword1] = useState(false);
const [errorPassword2, setErrorPassword2] = useState(false); const [errorPassword2, setErrorPassword2] = useState(false);
const { createSuccessNotification, createErrorNotification } = useNotifications(); const { createSuccessNotification, createErrorNotification } = useNotifications();
const history = useHistory(); const navigate = useNavigate();
// Get the token from the query param to give it back to the API when requesting // Get the token from the query param to give it back to the API when requesting
// the secret for OTP. // the secret for OTP.
const processToken = extractIdentityToken(location.search); const processToken = extractIdentityToken(location.search);
@ -69,7 +69,7 @@ const ResetPasswordStep2 = function () {
try { try {
await resetPassword(password1); await resetPassword(password1);
createSuccessNotification("Password has been reset."); createSuccessNotification("Password has been reset.");
setTimeout(() => history.push(FirstFactorRoute), 1500); setTimeout(() => navigate(FirstFactorRoute), 1500);
setFormDisabled(true); setFormDisabled(true);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@ -83,7 +83,7 @@ const ResetPasswordStep2 = function () {
const handleResetClick = () => doResetPassword(); const handleResetClick = () => doResetPassword();
const handleCancelClick = () => history.push(FirstFactorRoute); const handleCancelClick = () => navigate(FirstFactorRoute);
return ( return (
<LoginLayout title="Enter new password" id="reset-password-step2-stage"> <LoginLayout title="Enter new password" id="reset-password-step2-stage">