mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-26 08:47:36 +08:00
Add checks for password and email on signup and add field indicators for them (#3011) rizwanmustafa
* Add password length and strength check * Change regex * Add indicator * Fix bug * Revert autocomplete change * Add indicator for verify password * Add indicator for emails * Reorder code * Remove indicators when fields are empty * Show notification when email invalid on signup
This commit is contained in:
parent
44419bdb60
commit
9c5652113c
3 changed files with 257 additions and 41 deletions
|
|
@ -527,6 +527,18 @@ async function signUp(): Promise<void> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!email.match(
|
||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
)
|
||||
) {
|
||||
Notifications.add("Invalid email", 0, 3);
|
||||
LoginPage.hidePreloader();
|
||||
$(".pageLogin .button").removeClass("disabled");
|
||||
$(".pageLogin input").prop("disabled", false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (email !== emailVerify) {
|
||||
Notifications.add("Emails do not match", 0, 3);
|
||||
LoginPage.hidePreloader();
|
||||
|
|
@ -535,6 +547,30 @@ async function signUp(): Promise<void> {
|
|||
return;
|
||||
}
|
||||
|
||||
// Force user to use a capital letter, number, special character when setting up an account and changing password
|
||||
if (password.length < 8) {
|
||||
Notifications.add("Password must be at least 8 characters", 0, 3);
|
||||
LoginPage.hidePreloader();
|
||||
$(".pageLogin .button").removeClass("disabled");
|
||||
$(".pageLogin input").prop("disabled", false);
|
||||
return;
|
||||
}
|
||||
|
||||
const hasCapital = password.match(/[A-Z]/);
|
||||
const hasNumber = password.match(/[\d]/);
|
||||
const hasSpecial = password.match(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/);
|
||||
if (!hasCapital || !hasNumber || !hasSpecial) {
|
||||
Notifications.add(
|
||||
"Password must contain at least one capital letter, number, and special character",
|
||||
0,
|
||||
3
|
||||
);
|
||||
LoginPage.hidePreloader();
|
||||
$(".pageLogin .button").removeClass("disabled");
|
||||
$(".pageLogin input").prop("disabled", false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (password !== passwordVerify) {
|
||||
Notifications.add("Passwords do not match", 0, 3);
|
||||
LoginPage.hidePreloader();
|
||||
|
|
|
|||
|
|
@ -22,29 +22,6 @@ export function hidePreloader(): void {
|
|||
$(".pageLogin .preloader").addClass("hidden");
|
||||
}
|
||||
|
||||
const nameIndicator = new InputIndicator(
|
||||
$(".page.pageLogin .register.side .username.inputAndIndicator"),
|
||||
{
|
||||
available: {
|
||||
icon: "fa-check",
|
||||
level: 1,
|
||||
},
|
||||
unavailable: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
taken: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
checking: {
|
||||
icon: "fa-circle-notch",
|
||||
spinIcon: true,
|
||||
level: 0,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const checkNameDebounced = debounce(1000, async () => {
|
||||
const val = $(
|
||||
".page.pageLogin .register.side .usernameInput"
|
||||
|
|
@ -76,6 +53,142 @@ const checkNameDebounced = debounce(1000, async () => {
|
|||
}
|
||||
});
|
||||
|
||||
const checkEmailsMatch = (): void => {
|
||||
const email = $(".page.pageLogin .register.side .emailInput").val();
|
||||
const verifyEmail = $(
|
||||
".page.pageLogin .register.side .verifyEmailInput"
|
||||
).val();
|
||||
verifyEmailIndicator.show(email === verifyEmail ? "match" : "mismatch");
|
||||
};
|
||||
|
||||
const checkEmail = (): void => {
|
||||
const emailRegex =
|
||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
|
||||
const email = $(".page.pageLogin .register.side .emailInput").val() as string;
|
||||
|
||||
emailIndicator.show(emailRegex.test(email) ? "valid" : "invalid");
|
||||
};
|
||||
|
||||
const checkPassword = (): void => {
|
||||
passwordIndicator.show("good");
|
||||
const password = $(
|
||||
".page.pageLogin .register.side .passwordInput"
|
||||
).val() as string;
|
||||
|
||||
// Force user to use a capital letter, number, special character when setting up an account and changing password
|
||||
if (password.length < 8) {
|
||||
passwordIndicator.show("short", "Password must be at least 8 characters");
|
||||
return;
|
||||
}
|
||||
|
||||
const hasCapital = password.match(/[A-Z]/);
|
||||
const hasNumber = password.match(/[\d]/);
|
||||
const hasSpecial = password.match(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/);
|
||||
if (!hasCapital || !hasNumber || !hasSpecial) {
|
||||
passwordIndicator.show(
|
||||
"weak",
|
||||
"Password must contain at least one capital letter, number, and special character"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
passwordIndicator.show("good", "Password is good");
|
||||
};
|
||||
|
||||
const checkPasswordsMatch = (): void => {
|
||||
const password = $(".page.pageLogin .register.side .passwordInput").val();
|
||||
const verifyPassword = $(
|
||||
".page.pageLogin .register.side .verifyPasswordInput"
|
||||
).val();
|
||||
verifyPasswordIndicator.show(
|
||||
password === verifyPassword ? "match" : "mismatch"
|
||||
);
|
||||
};
|
||||
|
||||
const nameIndicator = new InputIndicator(
|
||||
$(".page.pageLogin .register.side .username.inputAndIndicator"),
|
||||
{
|
||||
available: {
|
||||
icon: "fa-check",
|
||||
level: 1,
|
||||
},
|
||||
unavailable: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
taken: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
checking: {
|
||||
icon: "fa-circle-notch",
|
||||
spinIcon: true,
|
||||
level: 0,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const emailIndicator = new InputIndicator(
|
||||
$(".page.pageLogin .register.side .email.inputAndIndicator"),
|
||||
{
|
||||
valid: {
|
||||
icon: "fa-check",
|
||||
level: 1,
|
||||
},
|
||||
invalid: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const verifyEmailIndicator = new InputIndicator(
|
||||
$(".page.pageLogin .register.side .verifyEmail.inputAndIndicator"),
|
||||
{
|
||||
match: {
|
||||
icon: "fa-check",
|
||||
level: 1,
|
||||
},
|
||||
mismatch: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const passwordIndicator = new InputIndicator(
|
||||
$(".page.pageLogin .register.side .password.inputAndIndicator"),
|
||||
{
|
||||
good: {
|
||||
icon: "fa-check",
|
||||
level: 1,
|
||||
},
|
||||
short: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
weak: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const verifyPasswordIndicator = new InputIndicator(
|
||||
$(".page.pageLogin .register.side .verifyPassword.inputAndIndicator"),
|
||||
{
|
||||
match: {
|
||||
icon: "fa-check",
|
||||
level: 1,
|
||||
},
|
||||
mismatch: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
$(".page.pageLogin .register.side .usernameInput").on("input", () => {
|
||||
setTimeout(() => {
|
||||
const val = $(
|
||||
|
|
@ -90,6 +203,57 @@ $(".page.pageLogin .register.side .usernameInput").on("input", () => {
|
|||
}, 1);
|
||||
});
|
||||
|
||||
$(".page.pageLogin .register.side .emailInput").on("input", () => {
|
||||
if (
|
||||
!$(".page.pageLogin .register.side .emailInput").val() &&
|
||||
!$(".page.pageLogin .register.side .verifyEmailInput").val()
|
||||
) {
|
||||
emailIndicator.hide();
|
||||
verifyEmailIndicator.hide();
|
||||
return;
|
||||
}
|
||||
checkEmail();
|
||||
checkEmailsMatch();
|
||||
});
|
||||
|
||||
$(".page.pageLogin .register.side .verifyEmailInput").on("input", () => {
|
||||
if (
|
||||
!$(".page.pageLogin .register.side .emailInput").val() &&
|
||||
!$(".page.pageLogin .register.side .verifyEmailInput").val()
|
||||
) {
|
||||
emailIndicator.hide();
|
||||
verifyEmailIndicator.hide();
|
||||
return;
|
||||
}
|
||||
checkEmailsMatch();
|
||||
});
|
||||
|
||||
$(".page.pageLogin .register.side .passwordInput").on("input", () => {
|
||||
if (
|
||||
!$(".page.pageLogin .register.side .passwordInput").val() &&
|
||||
!$(".page.pageLogin .register.side .verifyPasswordInput").val()
|
||||
) {
|
||||
passwordIndicator.hide();
|
||||
verifyPasswordIndicator.hide();
|
||||
return;
|
||||
}
|
||||
checkPassword();
|
||||
checkPasswordsMatch();
|
||||
});
|
||||
|
||||
$(".page.pageLogin .register.side .verifyPasswordInput").on("input", () => {
|
||||
if (
|
||||
!$(".page.pageLogin .register.side .passwordInput").val() &&
|
||||
!$(".page.pageLogin .register.side .verifyPasswordInput").val()
|
||||
) {
|
||||
passwordIndicator.hide();
|
||||
verifyPasswordIndicator.hide();
|
||||
return;
|
||||
}
|
||||
checkPassword();
|
||||
checkPasswordsMatch();
|
||||
});
|
||||
|
||||
export const page = new Page(
|
||||
"login",
|
||||
$(".page.pageLogin"),
|
||||
|
|
|
|||
|
|
@ -13,24 +13,40 @@
|
|||
autocomplete="new-username"
|
||||
/>
|
||||
</div>
|
||||
<input type="email" placeholder="email" autocomplete="new-email" />
|
||||
<input
|
||||
type="email"
|
||||
placeholder="verify email"
|
||||
autocomplete="verify-email"
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="password"
|
||||
autocomplete="new-password"
|
||||
name="new-password"
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="verify password"
|
||||
autocomplete="verify-password"
|
||||
name="verify-password"
|
||||
/>
|
||||
<div class="inputAndIndicator email">
|
||||
<input
|
||||
type="email"
|
||||
class="emailInput"
|
||||
placeholder="email"
|
||||
autocomplete="new-email"
|
||||
/>
|
||||
</div>
|
||||
<div class="inputAndIndicator verifyEmail">
|
||||
<input
|
||||
type="email"
|
||||
class="verifyEmailInput"
|
||||
placeholder="verify email"
|
||||
autocomplete="verify-email"
|
||||
/>
|
||||
</div>
|
||||
<div class="inputAndIndicator password">
|
||||
<input
|
||||
type="password"
|
||||
class="passwordInput"
|
||||
placeholder="password"
|
||||
autocomplete="new-password"
|
||||
name="new-password"
|
||||
/>
|
||||
</div>
|
||||
<div class="inputAndIndicator verifyPassword">
|
||||
<input
|
||||
type="password"
|
||||
class="verifyPasswordInput"
|
||||
placeholder="verify password"
|
||||
autocomplete="verify-password"
|
||||
name="verify-password"
|
||||
/>
|
||||
</div>
|
||||
<div class="button">
|
||||
<i class="fas fa-user-plus"></i>
|
||||
Sign Up
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue