Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MBF 7 - Implement password validator new design #158

Merged
merged 1 commit into from
May 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 88 additions & 8 deletions src/features/registration/components/registration-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import {
Text,
VStack,
Input,
Center,
Icon,
HStack,
} from "@chakra-ui/react";
import { ViewIcon, ViewOffIcon } from "@chakra-ui/icons";
import { useState } from "react";
Expand All @@ -15,8 +18,13 @@ import {
// DoPasswordsMatch,
IsValidEmail,
IsValidName,
PasswordContainsLowercase,
PasswordContainsNumber,
PasswordContainsSymbol,
PasswordContainsUppercase,
} from "../../../utilities/validators";
import SignIn from "./sign-in";
import { ImCheckboxChecked, ImCross } from 'react-icons/im'

export default function RegistrationForm() {
const [input, setInput] = useState({
Expand All @@ -31,7 +39,7 @@ export default function RegistrationForm() {
givenName: "",
famName: "",
email: "",
password: "",
password: { text: "", numChecked: 0, color: "", checks: { "Minimum length": false, "Number": false, "Symbol": false, "Uppercase": false, "Lowercase": false } },
confirmPassword: "",
valid: false,
});
Expand Down Expand Up @@ -63,7 +71,12 @@ export default function RegistrationForm() {
const validateInput = (event: any) => {
let { name, value } = event.target;
setError((prev) => {
const errorState = { ...prev, [name]: "" };
let errorState;
if (name == "password") {
errorState = { ...prev }
} else {
errorState = { ...prev, [name]: "" };
}
errorState.valid = canEnableSignUpButton();

switch (name) {
Expand All @@ -90,12 +103,65 @@ export default function RegistrationForm() {
// case "confirmPassword":
setNoText(typeof value != "undefined" && value.length < 1);

if (input.password && !IsPasswordMinLength(value)) {
errorState.password =
"Password must have a minimum of 8 characters, contain numbers, symbols, uppercase and lowercase characters.";
errorState.password.text = "Strong, your password is secure 💪";
errorState.password.checks = { "Minimum length": true, "Number": true, "Symbol": true, "Uppercase": true, "Lowercase": true };

let numChecked = 5;

if (!PasswordContainsSymbol(value)) {
errorState.password.text = "Almost there, add a special symbol 😉"
errorState.password.checks["Symbol"] = false
errorState.valid = false;
} else {
errorState.password = "";
numChecked -= 1;
}

if (!PasswordContainsNumber(value)) {
errorState.password.text = "So-so, should be alphanumeric 😕"
errorState.password.checks["Number"] = false
errorState.valid = false;
numChecked -= 1;
}

if (!PasswordContainsUppercase(value)) {
errorState.password.text =
"Weak, must have at one uppercase and lowercase letter 😖";
errorState.password.checks["Uppercase"] = false
errorState.valid = false;
numChecked -= 1;
}

if (!PasswordContainsLowercase(value)) {
errorState.password.text =
"Weak, must have at one uppercase and lowercase letter 😖";
errorState.password.checks["Lowercase"] = false
errorState.valid = false;
numChecked -= 1;
}

if (!IsPasswordMinLength(value)) {
errorState.password.text =
"Must have at least 8 characters.";
errorState.password.checks["Minimum length"] = false
errorState.valid = false;
numChecked -= 1;
}

errorState.password.numChecked = numChecked;
switch (numChecked) {
case 1:
errorState.password.color = "red";
break;
case 2:
case 3:
errorState.password.color = "yellow.300";
break;
case 4:
errorState.password.color = "blue";
break;
case 5:
default:
errorState.password.color = "green.400";
break;
}

// if (!DoPasswordsMatch(input.password, value)) {
Expand Down Expand Up @@ -167,7 +233,21 @@ export default function RegistrationForm() {
</Button>
</InputRightElement>
</InputGroup>
{error.password && <Box className="errorMsg">{error.password}</Box>}
</Box>
<Box>
<Center><Box w={0} h={0} filter="drop-shadow(0 -2px 2px #AAA)" borderLeft="20px solid transparent" borderRight="20px solid transparent" borderBottom="20px solid white" /></Center>
<Box boxShadow="0px 0px 8px #AAA" rounded="lg" p={3}>
<Text>{error.password.text}</Text>
<HStack spacing={2} py={4}>
{[...Array(error.password.numChecked)].map(() => <Box h={1} bg={error.password.color} flexGrow={1} />)}
{[...Array(5 - error.password.numChecked)].map(() => <Box h={1} bg="gray.300" flexGrow={1} />)}
</HStack>
<VStack alignItems="flex-start" spacing={1}>
{Object.entries(error.password.checks).map(([item, checked]) => (
<HStack spacing={2}><Icon as={checked ? ImCheckboxChecked : ImCross} color={checked ? "green.400" : "red"} /><Text>{item}</Text></HStack>
))}
</VStack>
</Box>
</Box>
{/* <Box>
<Text>Confirm Password</Text>
Expand Down
19 changes: 18 additions & 1 deletion src/utilities/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,24 @@ export function IsPasswordMinLength(password: string) {
// var letter = /[a-zA-Z]/;
// var number = /[0-9]/;
// var valid = number.test(password) && letter.test(password); //match a letter _and_ a number
return /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/.test(password) && password.length >= 8;
// return /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/.test(password) && password.length >= 8;
return password.length >= 8;
}

export function PasswordContainsNumber(password: string) {
return /^(?=.*?[0-9]).+$/.test(password);
}

export function PasswordContainsSymbol(password: string) {
return /^(?=.*?[#?!@$%^&*-]).+$/.test(password);
}

export function PasswordContainsUppercase(password: string) {
return /^(?=.*?[A-Z]).+$/.test(password);
}

export function PasswordContainsLowercase(password: string) {
return /^(?=.*?[a-z]).+$/.test(password);
}


Expand Down
Loading