174 lines
5.6 KiB
TypeScript
174 lines
5.6 KiB
TypeScript
import React, { useState } from "react";
|
|
import authentication from "../services/authenticationService";
|
|
import { IEmailUserAction } from "../models/IEmailUserAction";
|
|
import { InputType } from "../../../components/common/Input";
|
|
import Input from "../../../components/common/Input";
|
|
import Button, { ButtonType } from "../../../components/common/Button";
|
|
import ErrorBlock from "../../../components/common/ErrorBlock";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Namespaces } from "../../../i18n/i18n";
|
|
|
|
export interface EmailUserActionConfirmEmailData extends FormData {
|
|
password: string;
|
|
confirmPassword: string;
|
|
emailConfirmed: boolean;
|
|
}
|
|
|
|
interface Props {
|
|
emailUserAction: IEmailUserAction;
|
|
}
|
|
|
|
const EmailUserActionConfirmEmail: React.FC<Props> = ({ emailUserAction }) => {
|
|
const { t } = useTranslation(Namespaces.Common);
|
|
const [password, setPassword] = useState("");
|
|
const [confirmPassword, setConfirmPassword] = useState("");
|
|
const [emailConfirmed, setEmailConfirmed] = useState(false);
|
|
const [generalError, setGeneralError] = useState("");
|
|
const [errors, setErrors] = useState<{ [key: string]: string }>({});
|
|
const [hasTwelveCharacters, setHasTwelveCharacters] = useState(false);
|
|
const [hasSpecialCharacter, setHasSpecialCharacter] = useState(false);
|
|
const [hasUppercaseLetter, setHasUppercaseLetter] = useState(false);
|
|
const [hasLowercaseLetter, setHasLowercaseLetter] = useState(false);
|
|
const [hasNumber, setHasNumber] = useState(false);
|
|
|
|
const LABEL_PASSWORD = t("Password");
|
|
const LABEL_CONFIRM_PASSWORD = t("Confirmassword");
|
|
const LABEL_CONFIRM_EMAIL = t("Activate");
|
|
const PASSWORD_MAX_LENGTH = 255;
|
|
|
|
const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
const newPassword = e.currentTarget.value;
|
|
setPassword(newPassword);
|
|
setConfirmPassword("");
|
|
setHasNumber(/\d+/g.test(newPassword));
|
|
setHasLowercaseLetter(/[a-z]/g.test(newPassword));
|
|
setHasUppercaseLetter(/[A-Z]/g.test(newPassword));
|
|
setHasSpecialCharacter(
|
|
/[ ~`! @#$%^&*()_+\-=[\]{};:\\|,.'"<>/?]/.test(newPassword),
|
|
);
|
|
setHasTwelveCharacters(newPassword.length >= 12);
|
|
};
|
|
|
|
const handleConfirmPasswordChange = (
|
|
e: React.ChangeEvent<HTMLInputElement>,
|
|
) => {
|
|
setConfirmPassword(e.currentTarget.value);
|
|
};
|
|
|
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
const newErrors: { [key: string]: string } = {};
|
|
|
|
const minPasswordLength = 12;
|
|
|
|
// Validation
|
|
if (!password) {
|
|
newErrors.password = t("PasswordIsRequired");
|
|
} else if (password.length < minPasswordLength) {
|
|
newErrors.password = t("PasswordMinLength", {
|
|
minPasswordLength: minPasswordLength,
|
|
});
|
|
}
|
|
|
|
if (password && password !== confirmPassword) {
|
|
newErrors.confirmPassword = t("PasswordsMustMatch");
|
|
}
|
|
|
|
if (Object.keys(newErrors).length > 0) {
|
|
setErrors(newErrors);
|
|
return;
|
|
}
|
|
|
|
setErrors({});
|
|
|
|
try {
|
|
const action: IEmailUserAction = {
|
|
email: emailUserAction.email,
|
|
token: emailUserAction.token,
|
|
password: password,
|
|
emailActionType: emailUserAction.emailActionType,
|
|
};
|
|
|
|
const callResult = await authentication.completeEmailAction(action);
|
|
if (callResult === 1) {
|
|
setEmailConfirmed(true);
|
|
setTimeout(() => {
|
|
window.location.replace("/login");
|
|
}, 1000);
|
|
}
|
|
} catch (ex: any) {
|
|
setGeneralError(ex?.message || t("AnErrorOccurred"));
|
|
}
|
|
};
|
|
|
|
const isFormValid =
|
|
password !== "" &&
|
|
password === confirmPassword &&
|
|
hasNumber &&
|
|
hasLowercaseLetter &&
|
|
hasSpecialCharacter &&
|
|
hasUppercaseLetter &&
|
|
hasTwelveCharacters;
|
|
|
|
if (emailConfirmed) {
|
|
return (
|
|
<div className="alert alert-info">
|
|
Success, your e-mail is confirmed. You can now log in.
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div>To activate your account, please enter a password</div>
|
|
|
|
<form onSubmit={handleSubmit}>
|
|
{generalError && <ErrorBlock error={generalError} />}
|
|
<Input
|
|
name="password"
|
|
label={LABEL_PASSWORD}
|
|
type={InputType.password}
|
|
value={password}
|
|
onChange={handlePasswordChange}
|
|
maxLength={PASSWORD_MAX_LENGTH}
|
|
error={errors.password}
|
|
/>
|
|
<div className={hasTwelveCharacters ? "checked" : "unchecked"}>
|
|
Password requires a minimum of 12 characters containing a combination
|
|
of:
|
|
</div>
|
|
<ul>
|
|
<li className={hasSpecialCharacter ? "checked" : ""}>
|
|
At least 1 symbol
|
|
</li>
|
|
<li className={hasNumber ? "checked" : ""}>At least 1 number</li>
|
|
<li className={hasLowercaseLetter ? "checked" : ""}>
|
|
At least 1 lowercase letter
|
|
</li>
|
|
<li className={hasUppercaseLetter ? "checked" : ""}>
|
|
At least 1 uppercase letter
|
|
</li>
|
|
</ul>
|
|
<Input
|
|
name="confirmPassword"
|
|
label={LABEL_CONFIRM_PASSWORD}
|
|
type={InputType.password}
|
|
value={confirmPassword}
|
|
onChange={handleConfirmPasswordChange}
|
|
maxLength={PASSWORD_MAX_LENGTH}
|
|
error={errors.confirmPassword}
|
|
/>
|
|
<Button
|
|
buttonType={ButtonType.primary}
|
|
disabled={!isFormValid}
|
|
onClick={() => {}}
|
|
>
|
|
{LABEL_CONFIRM_EMAIL}
|
|
</Button>
|
|
</form>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default EmailUserActionConfirmEmail;
|