2019-11-19 06:37:36 +07:00
|
|
|
import React, { useState, useCallback, useEffect } from "react";
|
2021-01-02 17:58:24 +07:00
|
|
|
|
2019-11-19 06:37:36 +07:00
|
|
|
import { Grid, Button, makeStyles } from "@material-ui/core";
|
2021-01-02 17:58:24 +07:00
|
|
|
import classnames from "classnames";
|
2019-11-19 06:37:36 +07:00
|
|
|
import { useHistory, useLocation } from "react-router";
|
2021-01-02 17:58:24 +07:00
|
|
|
|
2021-06-19 15:20:43 +07:00
|
|
|
import FixedTextField from "@components/FixedTextField";
|
|
|
|
import { FirstFactorRoute } from "@constants/Routes";
|
|
|
|
import { useNotifications } from "@hooks/NotificationsContext";
|
|
|
|
import LoginLayout from "@layouts/LoginLayout";
|
|
|
|
import { completeResetPasswordProcess, resetPassword } from "@services/ResetPassword";
|
|
|
|
import { extractIdentityToken } from "@utils/IdentityToken";
|
2019-11-19 06:37:36 +07:00
|
|
|
|
2020-11-07 09:06:18 +07:00
|
|
|
const ResetPasswordStep2 = function () {
|
2019-11-19 06:37:36 +07:00
|
|
|
const style = useStyles();
|
|
|
|
const location = useLocation();
|
|
|
|
const [formDisabled, setFormDisabled] = useState(true);
|
|
|
|
const [password1, setPassword1] = useState("");
|
|
|
|
const [password2, setPassword2] = useState("");
|
|
|
|
const [errorPassword1, setErrorPassword1] = useState(false);
|
|
|
|
const [errorPassword2, setErrorPassword2] = useState(false);
|
|
|
|
const { createSuccessNotification, createErrorNotification } = useNotifications();
|
|
|
|
const history = useHistory();
|
|
|
|
// Get the token from the query param to give it back to the API when requesting
|
|
|
|
// the secret for OTP.
|
|
|
|
const processToken = extractIdentityToken(location.search);
|
|
|
|
|
|
|
|
const completeProcess = useCallback(async () => {
|
|
|
|
if (!processToken) {
|
|
|
|
setFormDisabled(true);
|
|
|
|
createErrorNotification("No verification token provided");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
setFormDisabled(true);
|
|
|
|
await completeResetPasswordProcess(processToken);
|
|
|
|
setFormDisabled(false);
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err);
|
2021-01-02 17:58:24 +07:00
|
|
|
createErrorNotification(
|
|
|
|
"There was an issue completing the process. The verification token might have expired.",
|
|
|
|
);
|
2019-11-19 06:37:36 +07:00
|
|
|
setFormDisabled(true);
|
|
|
|
}
|
|
|
|
}, [processToken, createErrorNotification]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
completeProcess();
|
|
|
|
}, [completeProcess]);
|
|
|
|
|
|
|
|
const doResetPassword = async () => {
|
|
|
|
if (password1 === "" || password2 === "") {
|
|
|
|
if (password1 === "") {
|
|
|
|
setErrorPassword1(true);
|
|
|
|
}
|
|
|
|
if (password2 === "") {
|
|
|
|
setErrorPassword2(true);
|
|
|
|
}
|
2021-01-02 17:58:24 +07:00
|
|
|
return;
|
2019-11-19 06:37:36 +07:00
|
|
|
}
|
2019-11-25 03:27:59 +07:00
|
|
|
if (password1 !== password2) {
|
|
|
|
setErrorPassword1(true);
|
2021-01-02 17:58:24 +07:00
|
|
|
setErrorPassword2(true);
|
2019-11-25 03:27:59 +07:00
|
|
|
createErrorNotification("Passwords do not match.");
|
|
|
|
return;
|
|
|
|
}
|
2019-11-19 06:37:36 +07:00
|
|
|
|
|
|
|
try {
|
|
|
|
await resetPassword(password1);
|
2019-11-25 03:27:59 +07:00
|
|
|
createSuccessNotification("Password has been reset.");
|
2019-11-19 06:37:36 +07:00
|
|
|
setTimeout(() => history.push(FirstFactorRoute), 1500);
|
|
|
|
setFormDisabled(true);
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err);
|
2021-09-04 20:27:11 +07:00
|
|
|
if ((err as Error).message.includes("0000052D.")) {
|
2020-11-27 16:59:22 +07:00
|
|
|
createErrorNotification("Your supplied password does not meet the password policy requirements.");
|
|
|
|
} else {
|
|
|
|
createErrorNotification("There was an issue resetting the password.");
|
|
|
|
}
|
2019-11-19 06:37:36 +07:00
|
|
|
}
|
2021-01-02 17:58:24 +07:00
|
|
|
};
|
2019-11-19 06:37:36 +07:00
|
|
|
|
2021-01-02 17:58:24 +07:00
|
|
|
const handleResetClick = () => doResetPassword();
|
2019-11-19 06:37:36 +07:00
|
|
|
|
2021-01-02 17:58:24 +07:00
|
|
|
const handleCancelClick = () => history.push(FirstFactorRoute);
|
2019-11-19 06:37:36 +07:00
|
|
|
|
|
|
|
return (
|
2019-11-25 03:27:59 +07:00
|
|
|
<LoginLayout title="Enter new password" id="reset-password-step2-stage">
|
2019-11-19 06:37:36 +07:00
|
|
|
<Grid container className={style.root} spacing={2}>
|
|
|
|
<Grid item xs={12}>
|
|
|
|
<FixedTextField
|
2019-11-25 03:27:59 +07:00
|
|
|
id="password1-textfield"
|
2019-11-19 06:37:36 +07:00
|
|
|
label="New password"
|
|
|
|
variant="outlined"
|
|
|
|
type="password"
|
|
|
|
value={password1}
|
|
|
|
disabled={formDisabled}
|
2021-01-02 17:58:24 +07:00
|
|
|
onChange={(e) => setPassword1(e.target.value)}
|
2019-11-19 06:37:36 +07:00
|
|
|
error={errorPassword1}
|
2021-01-02 17:58:24 +07:00
|
|
|
className={classnames(style.fullWidth)}
|
2021-07-01 00:04:55 +07:00
|
|
|
autoComplete="new-password"
|
2021-01-02 17:58:24 +07:00
|
|
|
/>
|
2019-11-19 06:37:36 +07:00
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12}>
|
|
|
|
<FixedTextField
|
2019-11-25 03:27:59 +07:00
|
|
|
id="password2-textfield"
|
2019-11-19 06:37:36 +07:00
|
|
|
label="Repeat new password"
|
|
|
|
variant="outlined"
|
|
|
|
type="password"
|
|
|
|
disabled={formDisabled}
|
|
|
|
value={password2}
|
2021-01-02 17:58:24 +07:00
|
|
|
onChange={(e) => setPassword2(e.target.value)}
|
2019-11-19 06:37:36 +07:00
|
|
|
error={errorPassword2}
|
|
|
|
onKeyPress={(ev) => {
|
2021-01-02 17:58:24 +07:00
|
|
|
if (ev.key === "Enter") {
|
2019-11-19 06:37:36 +07:00
|
|
|
doResetPassword();
|
|
|
|
ev.preventDefault();
|
|
|
|
}
|
|
|
|
}}
|
2021-01-02 17:58:24 +07:00
|
|
|
className={classnames(style.fullWidth)}
|
2021-07-01 00:04:55 +07:00
|
|
|
autoComplete="new-password"
|
2021-01-02 17:58:24 +07:00
|
|
|
/>
|
2019-11-19 06:37:36 +07:00
|
|
|
</Grid>
|
|
|
|
<Grid item xs={6}>
|
|
|
|
<Button
|
2019-11-25 03:27:59 +07:00
|
|
|
id="reset-button"
|
2019-11-19 06:37:36 +07:00
|
|
|
variant="contained"
|
|
|
|
color="primary"
|
|
|
|
name="password1"
|
|
|
|
disabled={formDisabled}
|
|
|
|
onClick={handleResetClick}
|
2021-01-02 17:58:24 +07:00
|
|
|
className={style.fullWidth}
|
|
|
|
>
|
|
|
|
Reset
|
|
|
|
</Button>
|
2019-11-19 06:37:36 +07:00
|
|
|
</Grid>
|
|
|
|
<Grid item xs={6}>
|
|
|
|
<Button
|
2019-11-25 03:27:59 +07:00
|
|
|
id="cancel-button"
|
2019-11-19 06:37:36 +07:00
|
|
|
variant="contained"
|
|
|
|
color="primary"
|
|
|
|
name="password2"
|
|
|
|
onClick={handleCancelClick}
|
2021-01-02 17:58:24 +07:00
|
|
|
className={style.fullWidth}
|
|
|
|
>
|
|
|
|
Cancel
|
|
|
|
</Button>
|
2019-11-19 06:37:36 +07:00
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
</LoginLayout>
|
2021-01-02 17:58:24 +07:00
|
|
|
);
|
|
|
|
};
|
2019-11-19 06:37:36 +07:00
|
|
|
|
2021-01-02 17:58:24 +07:00
|
|
|
export default ResetPasswordStep2;
|
2020-11-07 09:06:18 +07:00
|
|
|
|
2021-01-02 17:58:24 +07:00
|
|
|
const useStyles = makeStyles((theme) => ({
|
2019-11-19 06:37:36 +07:00
|
|
|
root: {
|
|
|
|
marginTop: theme.spacing(2),
|
|
|
|
marginBottom: theme.spacing(2),
|
|
|
|
},
|
|
|
|
fullWidth: {
|
|
|
|
width: "100%",
|
2021-01-02 17:58:24 +07:00
|
|
|
},
|
|
|
|
}));
|