Updated: All of the front end works!
This commit is contained in:
parent
ef66b9dbf9
commit
605e05fad1
1 changed files with 71 additions and 67 deletions
|
@ -6,49 +6,19 @@ import {useRef} from "react";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
|
||||||
// there's 100% a better way of handling multiple related states
|
const [passwordValue, setPasswordValue] = useState('');
|
||||||
// i'd need to redo how these states function as currently, they will only
|
const [confirmValue, setConfirmValue] = useState('');
|
||||||
// be considered valid when all of the checks pass AND one of the fields changes
|
const [passwordChangeResponseText, setPasswordChangeResponseText] = useState('');
|
||||||
// meaning that the passwords won't match correctly as i am checking whether they WERE valid PRIOR to one of them updating
|
const [passwordChangeStatus, setPasswordChangeStatus] = useState(false);
|
||||||
const [validPasswordLength, setValidPasswordLength] = useState(false);
|
|
||||||
const [validMinimumCharacters, setValidMinimumCharacters] = useState(false);
|
|
||||||
const [validSpecialCharacters, setValidSpecialCharacters] = useState(false);
|
|
||||||
const [validIdenticalPasswords, setValidIdenticalPasswords] = useState(false);
|
|
||||||
const passwordInput = useRef(null);
|
|
||||||
const confirmInput = useRef(null);
|
|
||||||
|
|
||||||
function handlePasswordFieldChange(e: React.ChangeEvent<HTMLInputElement>) {
|
function handlePasswordFieldChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||||
setValidPasswordLength(validatePasswordLength(e.target.value));
|
setPasswordChangeResponseText('');
|
||||||
setValidMinimumCharacters(validatePasswordMinimumCharacters(e.target.value));
|
setPasswordValue(e.target.value);
|
||||||
setValidSpecialCharacters(validatePasswordSpecialCharacters(e.target.value));
|
|
||||||
setValidIdenticalPasswords(validatePasswordsEqual(e.target.value));
|
|
||||||
console.log(validPasswordLength, validMinimumCharacters, validSpecialCharacters, validIdenticalPasswords);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function validatePasswordLength(password: string) {
|
// the following method is most likely overkill and is redundant with the other checks, however, i spent a while working out the regex and so it shall stay
|
||||||
// match any characters as long as the string is between 7 and 14 characters
|
|
||||||
const regex = new RegExp('^.{7,14}$');
|
|
||||||
return regex.test(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
function validatePasswordMinimumCharacters(password: string) {
|
const validatePassword = (password: string) => {
|
||||||
// look ahead for the special characters and digits and match them at least once
|
|
||||||
const regex = new RegExp('^(?=.*?[!£$^*#])(?=.*?[0-9]).*$');
|
|
||||||
return regex.test(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
function validatePasswordSpecialCharacters(password: string) {
|
|
||||||
// check for any characters not in the allowed list
|
|
||||||
const regex = new RegExp('([^a-zA-Z0-9!£$^*#\d\s])');
|
|
||||||
return !regex.test(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
function validatePasswordsEqual(password: string) {
|
|
||||||
// this feels wrong
|
|
||||||
return password === confirmInput.current.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isPasswordValidRegex(password: string) {
|
|
||||||
// following regex does the following:
|
// following regex does the following:
|
||||||
// ^ -> start of word
|
// ^ -> start of word
|
||||||
// (?=.*?[XXX]) -> look ahead / match any character / between zero and unlimited times/ that matches any of the characters in XXX
|
// (?=.*?[XXX]) -> look ahead / match any character / between zero and unlimited times/ that matches any of the characters in XXX
|
||||||
|
@ -57,24 +27,58 @@ export default function Home() {
|
||||||
// {7,14} -> match the previous tokens only between 7-14 times
|
// {7,14} -> match the previous tokens only between 7-14 times
|
||||||
// $ -> match the end of the password
|
// $ -> match the end of the password
|
||||||
const regex = new RegExp('^(?=.*?[a-zA-Z])(?=.*?[0-9])(?=.*?[!£$^*#])[a-zA-Z0-9!£$^*#]{7,14}$');
|
const regex = new RegExp('^(?=.*?[a-zA-Z])(?=.*?[0-9])(?=.*?[!£$^*#])[a-zA-Z0-9!£$^*#]{7,14}$');
|
||||||
console.log(regex.test(password));
|
|
||||||
return regex.test(password)
|
return regex.test(password)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const validatePasswordLength = (password: string) => {
|
||||||
|
const regex = new RegExp('^.{7,14}$');
|
||||||
|
return regex.test(password);
|
||||||
|
};
|
||||||
|
|
||||||
|
const validatePasswordMinimumCharacters = (password: string) => {
|
||||||
|
// look ahead for the special characters and digits and match them at least once
|
||||||
|
const regex = new RegExp('^(?=.*?[!£$^*#])(?=.*?[0-9]).*$');
|
||||||
|
return regex.test(password);
|
||||||
|
};
|
||||||
|
|
||||||
|
const validatePasswordSpecialCharacters = (password: string) => {
|
||||||
|
// check for any characters not in the allowed list
|
||||||
|
const regex = new RegExp('^[a-zA-Z0-9!£$^*#]*$');
|
||||||
|
return regex.test(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validatePasswordConfirmMatch = (passwordVal: string, confirmVal: string) => {
|
||||||
|
return passwordVal === confirmVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
const passwordValueValid = validatePassword(passwordValue);
|
||||||
|
const validPasswordLength = validatePasswordLength(passwordValue);
|
||||||
|
const validPasswordMinimumCharacters = validatePasswordMinimumCharacters(passwordValue);
|
||||||
|
const validPasswordSpecialCharacters = validatePasswordSpecialCharacters(passwordValue);
|
||||||
|
const validPasswordConfirmMatch = validatePasswordConfirmMatch(passwordValue, confirmValue);
|
||||||
|
const disableButton = !(validPasswordLength && validPasswordMinimumCharacters && validPasswordSpecialCharacters && validPasswordConfirmMatch);
|
||||||
|
|
||||||
async function handleFormSubmit(e: React.MouseEvent<HTMLButtonElement>) {
|
async function handleFormSubmit(e: React.MouseEvent<HTMLButtonElement>) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if(isPasswordValidRegex(passwordInput.current.value)
|
if(passwordValueValid && validPasswordLength && validPasswordMinimumCharacters && validPasswordSpecialCharacters) {
|
||||||
&& isPasswordValidRegex(confirmInput.current.value)
|
|
||||||
&& (confirmInput.current.value === passwordInput.current.value)) {
|
|
||||||
console.log("VALID PASSWORDS");
|
|
||||||
const response = await fetch("https://localhost:7144/Password/change", {
|
const response = await fetch("https://localhost:7144/Password/change", {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
body: JSON.stringify({password: passwordInput.current.value})
|
body: JSON.stringify({password: passwordValue})
|
||||||
});
|
});
|
||||||
console.log(response);
|
if(response.status == 200) {
|
||||||
|
console.log("SUCCESSFUL PASSWORD CHANGE");
|
||||||
|
setPasswordChangeResponseText('Password changed successfully!');
|
||||||
|
setPasswordChangeStatus(true);
|
||||||
}
|
}
|
||||||
console.log('Post password to back end');
|
else {
|
||||||
|
console.log("ERROR DURING PASSWORD CHANGE");
|
||||||
|
setPasswordChangeResponseText('Error during password change');
|
||||||
|
setPasswordChangeStatus(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// need to handle the response back
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -98,10 +102,10 @@ export default function Home() {
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<input
|
<input
|
||||||
id="password"
|
id="password"
|
||||||
ref={passwordInput}
|
|
||||||
name="password"
|
name="password"
|
||||||
type="password"
|
type="password"
|
||||||
data-testid="password"
|
data-testid="password"
|
||||||
|
value={passwordValue}
|
||||||
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||||
onChange={handlePasswordFieldChange}
|
onChange={handlePasswordFieldChange}
|
||||||
/>
|
/>
|
||||||
|
@ -117,38 +121,38 @@ export default function Home() {
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<input
|
<input
|
||||||
id="confirm"
|
id="confirm"
|
||||||
ref={confirmInput}
|
value={confirmValue}
|
||||||
name="confirm"
|
name="confirm"
|
||||||
type="password"
|
type="password"
|
||||||
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||||
onChange={handlePasswordFieldChange}
|
onChange={(e) => setConfirmValue(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
className={"flex w-full justify-center bg-gray-900 hover:bg-gray-700 active:bg-gray-800 px-4 py-2 rounded-md text-white"}
|
className={"flex w-full justify-center bg-gray-900 hover:bg-gray-700 active:bg-gray-800 disabled:cursor-not-allowed disabled:bg-gray-400 px-4 py-2 rounded-md text-white"}
|
||||||
onClick={(e) => handleFormSubmit(e)}>
|
onClick={(e) => handleFormSubmit(e)}
|
||||||
|
disabled={disableButton}>
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={`text-center text-l font-bold leading-9 tracking-tight ${passwordChangeStatus ? 'text-green-600' :'text-red-600'}`}>
|
||||||
|
{passwordChangeResponseText}
|
||||||
|
</div>
|
||||||
<div className="mx-auto text-xs mt-8">
|
<div className="mx-auto text-xs mt-8">
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
|
||||||
Password must be between 7-14 characters in length
|
<li className={`${validPasswordLength ? 'text-green-600 bi-check-lg' : 'text-red-600 bi-x-lg'}`}>
|
||||||
</li>
|
Password must be between 7-14 characters in length</li>
|
||||||
<li>
|
<li className={`${validPasswordMinimumCharacters ? 'text-green-600 bi-check-lg' : 'text-red-600 bi-x-lg'}`}>
|
||||||
Password must contain at least 1 number and one special characters
|
Password must contain at least 1 number and one special characters</li>
|
||||||
</li>
|
<li className={`${validPasswordSpecialCharacters ? 'text-green-600 bi-check-lg' : 'text-red-600 bi-x-lg'}`}>
|
||||||
<li>
|
Password does not contain special characters other than <code>!£$^*#</code></li>
|
||||||
Password does not contain special characters other than <code>!£$^*#</code>
|
<li className={`${validPasswordConfirmMatch ? 'text-green-600 bi-check-lg' : 'text-red-600 bi-x-lg'}`}>
|
||||||
</li>
|
Both passwords must be identical</li>
|
||||||
<li>
|
|
||||||
Both passwords must be identical
|
|
||||||
</li>
|
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue