Improved UI and compliance with api endpoint restrictions
This commit is contained in:
+62
-23
@@ -61,20 +61,36 @@ function isDisposableEmail(email) {
|
||||
);
|
||||
}
|
||||
|
||||
export function validateRegistration({ name, username, email, password }) {
|
||||
const trimmedName = name.trim();
|
||||
const trimmedUsername = username.trim();
|
||||
const normalizedEmail = email.trim().toLowerCase();
|
||||
function hasControlCharacter(value) {
|
||||
return [...value].some((character) => {
|
||||
const code = character.charCodeAt(0);
|
||||
return code <= 0x1f || code === 0x7f;
|
||||
});
|
||||
}
|
||||
|
||||
function validateName(name) {
|
||||
const trimmedName = name.trim();
|
||||
if (hasControlCharacter(name)) {
|
||||
return "Input contains unsupported control characters.";
|
||||
}
|
||||
if (trimmedName.length < 1 || trimmedName.length > 100) {
|
||||
return "Name must be between 1 and 100 characters.";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (trimmedUsername.length < 1 || trimmedUsername.length > 50 || /\s/.test(trimmedUsername)) {
|
||||
function validateUsername(username) {
|
||||
const trimmedUsername = username.trim();
|
||||
if (hasControlCharacter(username) || trimmedUsername.length < 1 || trimmedUsername.length > 50 || /\s/.test(trimmedUsername)) {
|
||||
return "Username must be between 1 and 50 characters and cannot contain whitespace.";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function validateEmail(email, { checkDisposable = false } = {}) {
|
||||
const normalizedEmail = email.trim().toLowerCase();
|
||||
if (
|
||||
hasControlCharacter(email) ||
|
||||
normalizedEmail.length < 1 ||
|
||||
normalizedEmail.length > 254 ||
|
||||
/\s/.test(normalizedEmail) ||
|
||||
@@ -82,8 +98,14 @@ export function validateRegistration({ name, username, email, password }) {
|
||||
) {
|
||||
return "Enter a valid email address without whitespace.";
|
||||
}
|
||||
if (checkDisposable && isDisposableEmail(normalizedEmail)) {
|
||||
return "Disposable or temporary email addresses are not allowed.";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (password.length < 1 || password.length > 128) {
|
||||
function validatePassword(password, username, email) {
|
||||
if (hasControlCharacter(password) || password.length < 1 || password.length > 128) {
|
||||
return "Password must be between 1 and 128 characters.";
|
||||
}
|
||||
|
||||
@@ -96,9 +118,14 @@ export function validateRegistration({ name, username, email, password }) {
|
||||
}
|
||||
|
||||
const passwordForComparison = password.toLowerCase();
|
||||
const { localPart } = getEmailParts(normalizedEmail);
|
||||
const trimmedUsername = username.trim();
|
||||
const normalizedEmail = email.trim().toLowerCase();
|
||||
const localPart = EMAIL_PATTERN.test(normalizedEmail) ? getEmailParts(normalizedEmail).localPart : "";
|
||||
|
||||
if (passwordForComparison.includes(trimmedUsername.toLowerCase()) || passwordForComparison.includes(localPart.toLowerCase())) {
|
||||
if (
|
||||
(trimmedUsername && passwordForComparison.includes(trimmedUsername.toLowerCase())) ||
|
||||
(localPart && passwordForComparison.includes(localPart.toLowerCase()))
|
||||
) {
|
||||
return "Password cannot contain your username or email address.";
|
||||
}
|
||||
|
||||
@@ -110,27 +137,42 @@ export function validateRegistration({ name, username, email, password }) {
|
||||
return "Password cannot contain repeated or sequential character patterns.";
|
||||
}
|
||||
|
||||
if (isDisposableEmail(normalizedEmail)) {
|
||||
return "Disposable or temporary email addresses are not allowed.";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function validateLogin({ email, password }) {
|
||||
const normalizedEmail = email.trim().toLowerCase();
|
||||
|
||||
if (normalizedEmail.length < 1 || normalizedEmail.length > 254 || /\s/.test(normalizedEmail) || !EMAIL_PATTERN.test(normalizedEmail)) {
|
||||
return "Enter a valid email address without whitespace.";
|
||||
}
|
||||
export function getRegistrationFieldErrors(form) {
|
||||
return {
|
||||
name: validateName(form.name),
|
||||
username: validateUsername(form.username),
|
||||
email: validateEmail(form.email, { checkDisposable: true }),
|
||||
password: validatePassword(form.password, form.username, form.email),
|
||||
};
|
||||
}
|
||||
|
||||
function validateLoginPassword(password) {
|
||||
if (password.length < 1 || password.length > 128) {
|
||||
return "Password must be between 1 and 128 characters.";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getLoginFieldErrors(form) {
|
||||
return {
|
||||
email: validateEmail(form.email),
|
||||
password: validateLoginPassword(form.password),
|
||||
};
|
||||
}
|
||||
|
||||
export function validateRegistration(form) {
|
||||
const errors = getRegistrationFieldErrors(form);
|
||||
return errors.name || errors.username || errors.email || errors.password || null;
|
||||
}
|
||||
|
||||
export function validateLogin({ email, password }) {
|
||||
const errors = getLoginFieldErrors({ email, password });
|
||||
return errors.email || errors.password || null;
|
||||
}
|
||||
|
||||
export function normalizeRegistrationData({ name, username, email, password }) {
|
||||
return {
|
||||
name: name.trim(),
|
||||
@@ -148,8 +190,5 @@ export function normalizeLoginData({ email, password }) {
|
||||
}
|
||||
|
||||
export function isControlCharacterPresent(value) {
|
||||
return [...value].some((character) => {
|
||||
const code = character.charCodeAt(0);
|
||||
return code <= 0x1f || code === 0x7f;
|
||||
});
|
||||
return hasControlCharacter(value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user