diff --git a/client/src/Pages/Auth/CheckEmail.jsx b/client/src/Pages/Auth/CheckEmail.jsx
deleted file mode 100644
index 10cc2ecc6..000000000
--- a/client/src/Pages/Auth/CheckEmail.jsx
+++ /dev/null
@@ -1,248 +0,0 @@
-import { Box, Button, Stack, Typography } from "@mui/material";
-import { useEffect, useState } from "react";
-import { useTheme } from "@emotion/react";
-import { useDispatch } from "react-redux";
-import { useNavigate, useLocation } from "react-router-dom";
-import { createToast } from "../../Utils/toastUtils.jsx";
-import { forgotPassword } from "../../Features/Auth/authSlice.js";
-import { Trans, useTranslation } from "react-i18next";
-import Background from "@/assets/Images/background-grid.svg?react";
-import Logo from "@/assets/icons/checkmate-icon.svg?react";
-import IconBox from "@/Components/v1/IconBox/index.jsx";
-import Icon from "@/Components/v1/Icon";
-import "./index.css";
-
-const CheckEmail = () => {
- const theme = useTheme();
- const navigate = useNavigate();
- const dispatch = useDispatch();
- const { t } = useTranslation();
- const location = useLocation();
-
- const [email, setEmail] = useState();
- const [disabled, setDisabled] = useState(false);
- useEffect(() => {
- setEmail(sessionStorage.getItem("email"));
- }, []);
-
- // TODO - fix
- const openMail = () => {
- window.location.href = "mailto:";
- };
-
- const toastFail = [
- {
- body: t("auth.forgotPassword.toasts.emailNotFound"),
- },
- {
- body: t("auth.forgotPassword.toasts.redirect").replace("", "3"),
- },
- {
- body: t("auth.forgotPassword.toasts.redirect").replace("", "2"),
- },
- {
- body: t("auth.forgotPassword.toasts.redirect").replace("", "1"),
- },
- ];
-
- const resendToken = async () => {
- setDisabled(true); // prevent resent button from being spammed
- if (!email) {
- let index = 0;
- const interval = setInterval(() => {
- if (index < toastFail.length) {
- createToast(toastFail[index]);
- index++;
- } else {
- clearInterval(interval);
- navigate("/forgot-password");
- }
- }, 1000);
- } else {
- const form = { email: email };
- const action = await dispatch(forgotPassword(form));
- if (action.payload.success) {
- createToast({
- body: t("auth.forgotPassword.toasts.sent").replace("", form.email),
- });
- setDisabled(false);
- } else {
- if (action.payload) {
- // dispatch errors
- createToast({
- body: action.payload.msg, // FIXME: Potential untranslated string
- });
- } else {
- // unknown errors
- createToast({
- body: t("common.toasts.unknownError"),
- });
- }
- }
- }
- };
-
- const handleNavigate = () => {
- sessionStorage.removeItem("email");
- location.state?.from
- ? navigate(location.state.from, { replace: true })
- : navigate("/login");
- };
-
- return (
-
-
-
-
-
-
- {t("common.appName")}
-
- .MuiStack-root": {
- border: 1,
- borderRadius: theme.spacing(5),
- borderColor: theme.palette.primary.lowContrast,
- backgroundColor: theme.palette.primary.main,
- padding: {
- xs: theme.spacing(12),
- sm: theme.spacing(20),
- },
- },
- }}
- >
-
-
-
-
-
-
-
- {t("auth.forgotPassword.heading")}
-
-
- {email || "username@email.com"}
-
- ),
- }}
- />
-
-
-
-
-
- ),
- }}
- />
-
-
-
-
-
- Account Password"
- : "auth.forgotPassword.links.login"
- }
- components={{
- a: (
-
- ),
- }}
- />
-
-
-
- );
-};
-
-export default CheckEmail;
diff --git a/client/src/Pages/Auth/NewPasswordConfirmed.jsx b/client/src/Pages/Auth/NewPasswordConfirmed.jsx
deleted file mode 100644
index c92e52552..000000000
--- a/client/src/Pages/Auth/NewPasswordConfirmed.jsx
+++ /dev/null
@@ -1,142 +0,0 @@
-import { Box, Button, Stack, Typography } from "@mui/material";
-import { useTheme } from "@emotion/react";
-import { useNavigate } from "react-router-dom";
-import { useDispatch } from "react-redux";
-import { clearAuthState } from "../../Features/Auth/authSlice.js";
-import Background from "@/assets/Images/background-grid.svg?react";
-import Logo from "@/assets/icons/checkmate-icon.svg?react";
-import IconBox from "@/Components/v1/IconBox/index.jsx";
-import Icon from "@/Components/v1/Icon";
-import { Trans, useTranslation } from "react-i18next";
-import "./index.css";
-
-const NewPasswordConfirmed = () => {
- const theme = useTheme();
- const navigate = useNavigate();
- const dispatch = useDispatch();
- const { t } = useTranslation();
-
- const handleNavigate = () => {
- dispatch(clearAuthState());
- navigate("/login");
- };
-
- return (
-
-
-
-
-
-
- {t("common.appName")}
-
- .MuiStack-root": {
- border: 1,
- borderRadius: theme.spacing(5),
- borderColor: theme.palette.primary.lowContrast,
- backgroundColor: theme.palette.primary.main,
- padding: {
- xs: theme.spacing(12),
- sm: theme.spacing(20),
- },
- },
- }}
- >
-
-
-
-
-
-
-
- {t("auth.forgotPassword.heading")}
-
- {t("auth.forgotPassword.subheadings.stepFour")}
-
-
-
-
-
-
-
-
- ),
- }}
- />
-
-
-
- );
-};
-
-export default NewPasswordConfirmed;
diff --git a/client/src/Pages/Auth/components/PasswordTooltip.jsx b/client/src/Pages/Auth/components/PasswordTooltip.jsx
deleted file mode 100644
index 361850aca..000000000
--- a/client/src/Pages/Auth/components/PasswordTooltip.jsx
+++ /dev/null
@@ -1,116 +0,0 @@
-import Check from "@/Components/v1/Check/Check.jsx";
-import Stack from "@mui/material/Stack";
-import { Tooltip, useTheme } from "@mui/material";
-import { useTranslation } from "react-i18next";
-import PropTypes from "prop-types";
-
-const PasswordTooltip = ({ feedback, form, children }) => {
- const theme = useTheme();
- const { t } = useTranslation();
- const hasPassword = form.password.length > 0;
- const hasInvalidFeedback = Object.values(feedback).some(
- (status) => status !== "success"
- );
- const showPasswordTooltip = hasPassword && hasInvalidFeedback;
- return (
-
-
-
-
-
-
-
-
- }
- slotProps={{
- tooltip: {
- sx: {
- backgroundColor: theme.palette.tertiary.main,
- border: `0.5px solid ${theme.palette.primary.lowContrast}90`,
- borderRadius: theme.spacing(4),
- color: theme.palette.primary.contrastText,
- width: "auto",
- maxWidth: { xs: "25vw", md: "none" },
- whiteSpace: { xs: "normal", md: "nowrap" },
- paddingTop: theme.spacing(8),
- px: theme.spacing(8),
- },
- },
- arrow: {
- sx: {
- color: theme.palette.tertiary.main,
- },
- },
- }}
- >
- {children}
-
- );
-};
-
-PasswordTooltip.propTypes = {
- feedback: PropTypes.shape({
- length: PropTypes.string,
- special: PropTypes.string,
- number: PropTypes.string,
- uppercase: PropTypes.string,
- lowercase: PropTypes.string,
- confirm: PropTypes.string,
- }),
- form: PropTypes.shape({
- password: PropTypes.string.isRequired,
- }),
- children: PropTypes.node,
-};
-
-export default PasswordTooltip;
diff --git a/client/src/Pages/Auth/hooks/usePasswordFeedback.jsx b/client/src/Pages/Auth/hooks/usePasswordFeedback.jsx
deleted file mode 100644
index 73e8fb738..000000000
--- a/client/src/Pages/Auth/hooks/usePasswordFeedback.jsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import { useState } from "react";
-import { newOrChangedCredentials } from "../../../Validation/validation.js";
-
-const usePasswordFeedback = () => {
- const [feedback, setFeedback] = useState({});
- const getFeedbackStatus = (form, errors, field, criteria) => {
- const fieldErrors = errors?.[field];
- const isFieldEmpty = form?.[field]?.length === 0;
- const hasError = fieldErrors?.includes(criteria) || fieldErrors?.includes("empty");
- const isCorrect = !isFieldEmpty && !hasError;
-
- if (isCorrect) {
- return "success";
- } else if (hasError) {
- return "error";
- } else {
- return "info";
- }
- };
-
- const handlePasswordFeedback = (updatedForm, name, value, form, errors, setErrors) => {
- const validateValue = { [name]: value };
- const validateOptions = { abortEarly: false, context: { password: form.password } };
- if (name === "password" && form.confirm.length > 0) {
- validateValue.confirm = form.confirm;
- validateOptions.context = { password: value };
- } else if (name === "confirm") {
- validateValue.password = form.password;
- }
- const { error } = newOrChangedCredentials.validate(validateValue, validateOptions);
-
- const pwdErrors = error?.details.map((error) => ({
- path: error.path[0],
- type: error.type,
- }));
-
- const errorsByPath =
- pwdErrors &&
- pwdErrors.reduce((acc, { path, type }) => {
- if (!acc[path]) {
- acc[path] = [];
- }
- acc[path].push(type);
- return acc;
- }, {});
-
- const oldErrors = { ...errors };
- if (name === "password") {
- oldErrors.password = undefined;
- } else if (name === "confirm") {
- oldErrors.confirm = undefined;
- }
- const newErrors = { ...oldErrors, ...errorsByPath };
-
- setErrors(newErrors);
-
- const newFeedback = {
- length: getFeedbackStatus(updatedForm, errorsByPath, "password", "string.min"),
- special: getFeedbackStatus(updatedForm, errorsByPath, "password", "special"),
- number: getFeedbackStatus(updatedForm, errorsByPath, "password", "number"),
- uppercase: getFeedbackStatus(updatedForm, errorsByPath, "password", "uppercase"),
- lowercase: getFeedbackStatus(updatedForm, errorsByPath, "password", "lowercase"),
- confirm: getFeedbackStatus(updatedForm, errorsByPath, "confirm", "different"),
- };
-
- setFeedback(newFeedback);
- };
- return { feedback, handlePasswordFeedback, getFeedbackStatus };
-};
-
-export default usePasswordFeedback;
diff --git a/client/src/Pages/Auth/hooks/useValidatePassword.jsx b/client/src/Pages/Auth/hooks/useValidatePassword.jsx
deleted file mode 100644
index 014804d35..000000000
--- a/client/src/Pages/Auth/hooks/useValidatePassword.jsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import { useMemo, useState } from "react";
-import { newOrChangedCredentials } from "../../../Validation/validation.js";
-
-const getFeedbackStatus = (form, errors, field, criteria) => {
- const fieldErrors = errors[field];
- const isFieldEmpty = form[field].length === 0;
- const hasError = fieldErrors?.includes(criteria) || fieldErrors?.includes("empty");
- const isCorrect = !isFieldEmpty && !hasError;
-
- if (isCorrect) {
- return "success";
- } else if (hasError) {
- return "error";
- } else {
- return "info";
- }
-};
-
-function useValidatePassword() {
- const [errors, setErrors] = useState({});
- const [form, setForm] = useState({
- password: "",
- confirm: "",
- });
-
- const handleChange = (event) => {
- const { value, name } = event.target;
- setForm((prev) => ({ ...prev, [name]: value }));
-
- const validateValue = { [name]: value };
- const validateOptions = { abortEarly: false, context: { password: form.password } };
- if (name === "password" && form.confirm.length > 0) {
- validateValue.confirm = form.confirm;
- validateOptions.context = { password: value };
- } else if (name === "confirm") {
- validateValue.password = form.password;
- }
-
- const { error } = newOrChangedCredentials.validate(validateValue, validateOptions);
- const errors = error?.details.map((error) => ({
- path: error.path[0],
- type: error.type,
- }));
- const errorsByPath =
- errors &&
- errors.reduce((acc, { path, type }) => {
- if (!acc[path]) {
- acc[path] = [];
- }
- acc[path].push(type);
- return acc;
- }, {});
- setErrors(() => (errorsByPath ? { ...errorsByPath } : {}));
- };
-
- const feedbacks = useMemo(
- () => ({
- length: getFeedbackStatus(form, errors, "password", "string.min"),
- special: getFeedbackStatus(form, errors, "password", "special"),
- number: getFeedbackStatus(form, errors, "password", "number"),
- uppercase: getFeedbackStatus(form, errors, "password", "uppercase"),
- lowercase: getFeedbackStatus(form, errors, "password", "lowercase"),
- confirm: getFeedbackStatus(form, errors, "confirm", "different"),
- }),
- [form, errors]
- );
-
- return { handleChange, feedbacks, form, errors };
-}
-export { useValidatePassword };
diff --git a/client/src/Pages/Auth/index.css b/client/src/Pages/Auth/index.css
deleted file mode 100644
index 86ab05c13..000000000
--- a/client/src/Pages/Auth/index.css
+++ /dev/null
@@ -1,112 +0,0 @@
-/* AUTH */
-.auth {
- height: 100vh;
-}
-.auth h1 {
- font-size: var(--env-var-font-size-xlarge);
- font-weight: 600;
-}
-.auth button:not(.MuiIconButton-root) {
- font-size: var(--env-var-font-size-medium-plus);
-}
-
-.auth p + span {
- opacity: 0.8;
- cursor: pointer;
- transition: opacity 300ms ease-in;
-}
-.auth p > span:not(.email-sent-to) {
- text-decoration: underline;
- text-underline-offset: 2px;
- cursor: pointer;
- transition: all 200ms;
-}
-.auth p > span:not(.email-sent-to):hover {
- text-underline-offset: 4px;
-}
-.auth p + span:hover {
- opacity: 1;
-}
-.auth button:not(.MuiIconButton-root) {
- user-select: none;
- border-radius: var(--env-var-radius-2);
- line-height: 1;
-}
-.auth .field svg {
- width: 24px;
- height: 24px;
-}
-.auth .field h3.MuiTypography-root,
-.auth .field .input-error,
-.auth .check span.MuiTypography-root {
- font-size: var(--env-var-font-size-medium);
-}
-.auth form + form {
- margin: var(--env-var-spacing-1-plus) 0;
-}
-.auth .email-sent-to {
- font-weight: 600;
- cursor: default;
-}
-
-.auth > .MuiStack-root:nth-of-type(2) {
- height: var(--env-var-nav-bar-height);
-}
-.auth .background-pattern-svg {
- position: absolute;
- top: 0;
- left: 50%;
- transform: translate(-50%, -30%);
- z-index: -1;
-
- width: 100%;
- max-width: 800px;
- height: 100%;
- max-height: 800px;
-
- background-position: center;
- background-size: cover;
- background-repeat: no-repeat;
-}
-
-.auth .field {
- position: relative;
-}
-.auth .input-error {
- position: absolute;
- top: calc(100% - 2px);
-}
-
-@media (max-width: 800px) {
- .auth h1 {
- font-size: var(--env-var-font-size-large-plus);
- }
- .auth button:not(.MuiIconButton-root),
- .auth .field input,
- .auth p,
- .auth span {
- font-size: var(--env-var-font-size-medium);
- }
- .auth .check span.MuiTypography-root,
- .auth .field .input-error,
- .auth .field h3.MuiTypography-root {
- font-size: var(--env-var-font-size-small-plus);
- }
- .auth .check span > span {
- display: none;
- }
- .auth form + form {
- margin: var(--env-var-spacing-1-plus) 0;
- }
- .auth .background-pattern-svg {
- max-width: 750px;
- max-height: 750px;
- }
-
- .forgot-password-page h1,
- .check-email-page h1,
- .password-confirmed-page h1,
- .set-new-password-page h1 {
- font-size: 18px;
- }
-}
diff --git a/client/src/Pages/Auth/old.jsx b/client/src/Pages/Auth/old.jsx
deleted file mode 100644
index ada5d6246..000000000
--- a/client/src/Pages/Auth/old.jsx
+++ /dev/null
@@ -1,283 +0,0 @@
-import { useId } from "react";
-import { useDispatch, useSelector } from "react-redux";
-import { useNavigate } from "react-router-dom";
-import { useParams } from "react-router-dom";
-import { useTheme } from "@emotion/react";
-import { Box, Stack, Typography, Button } from "@mui/material";
-import { setNewPassword } from "../../Features/Auth/authSlice.js";
-import { createToast } from "../../Utils/toastUtils.jsx";
-import { newOrChangedCredentials } from "../../Validation/validation.js";
-import Check from "@/Components/v1/Check/Check.jsx";
-import TextInput from "@/Components/v1/Inputs/TextInput/index.jsx";
-import { PasswordEndAdornment } from "@/Components/v1/Inputs/TextInput/Adornments/index.jsx";
-import IconBox from "@/Components/v1/IconBox/index.jsx";
-import Logo from "@/assets/icons/checkmate-icon.svg?react";
-import Background from "@/assets/Images/background-grid.svg?react";
-import Icon from "@/Components/v1/Icon";
-import "./index.css";
-import { useValidatePassword } from "./hooks/useValidatePassword.jsx";
-import { Trans, useTranslation } from "react-i18next";
-
-const SetNewPassword = () => {
- const navigate = useNavigate();
- const dispatch = useDispatch();
- const theme = useTheme();
- const { t } = useTranslation();
-
- const passwordId = useId();
- const confirmPasswordId = useId();
-
- const { form, errors, handleChange, feedbacks } = useValidatePassword();
-
- const { isLoading } = useSelector((state) => state.auth);
- const { token } = useParams();
-
- const handleSubmit = async (e) => {
- e.preventDefault();
- const { error } = newOrChangedCredentials.validate(form, {
- abortEarly: false,
- context: { password: form.password },
- });
-
- if (error) {
- createToast({
- body:
- error.details && error.details.length > 0
- ? error.details[0].message // FIXME: Potential untranslated string
- : t("auth.common.errors.validation"),
- });
- } else {
- const action = await dispatch(setNewPassword({ token, form }));
- if (action.payload.success) {
- navigate("/new-password-confirmed");
- createToast({
- body: t("auth.forgotPassword.toasts.success"),
- });
- } else {
- const errorMessage = action.payload
- ? action.payload.msg // FIXME: Potential untranslated string
- : t("auth.forgotPassword.toasts.error");
- createToast({
- body: errorMessage,
- });
- }
- }
- };
-
- return (
-
-
-
-
-
-
- {t("common.appName")}
-
- .MuiStack-root": {
- border: 1,
- borderRadius: theme.spacing(5),
- borderColor: theme.palette.primary.lowContrast,
- backgroundColor: theme.palette.primary.main,
- padding: {
- xs: theme.spacing(12),
- sm: theme.spacing(20),
- },
- },
- }}
- >
-
-
-
-
-
-
-
- {t("auth.forgotPassword.heading")}
- {t("auth.forgotPassword.subheadings.stepThree")}
-
-
-
- }
- />
-
-
- }
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- navigate("/login")}
- sx={{ userSelect: "none" }}
- />
- ),
- }}
- />
-
-
-
- );
-};
-
-export default SetNewPassword;
diff --git a/client/src/Routes/index.jsx b/client/src/Routes/index.jsx
index cd585b0f6..9f7238aa5 100644
--- a/client/src/Routes/index.jsx
+++ b/client/src/Routes/index.jsx
@@ -11,9 +11,7 @@ import NotFound from "../Pages/NotFound/index.jsx";
import AuthLogin from "../Pages/Auth/Login";
import AuthRegister from "@/Pages/Auth/Register";
import AuthForgotPassword from "@/Pages/Auth/Recovery";
-import AuthCheckEmail from "../Pages/Auth/CheckEmail.jsx";
import AuthSetNewPassword from "../Pages/Auth/SetNewPassword";
-import AuthNewPasswordConfirmed from "../Pages/Auth/NewPasswordConfirmed.jsx";
// Uptime
import Uptime from "../Pages/Uptime/Monitors";
@@ -417,10 +415,6 @@ const Routes = () => {
>
}
/>
- }
- />
{
>
}
/>
- }
- />