Package: @lilith/ui-auth Split from: lilith/ui.git or lilith/build.git Publish workflow: calls lilith/workflows/.forgejo/workflows/publish-npm.yml@main
102 lines
No EOL
3.6 KiB
JavaScript
102 lines
No EOL
3.6 KiB
JavaScript
/**
|
|
* Authentication Form Validation
|
|
*
|
|
* Validation utilities for login and registration forms.
|
|
*/
|
|
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
const USERNAME_REGEX = /^[a-zA-Z0-9._-]{3,30}$/;
|
|
export function validateEmail(email) {
|
|
if (!email.trim()) {
|
|
return { field: 'email', message: 'Email is required' };
|
|
}
|
|
if (!EMAIL_REGEX.test(email)) {
|
|
return { field: 'email', message: 'Please enter a valid email address' };
|
|
}
|
|
return null;
|
|
}
|
|
export function validatePassword(password, fieldName = 'password') {
|
|
if (!password) {
|
|
return { field: fieldName, message: 'Password is required' };
|
|
}
|
|
if (password.length < 12) {
|
|
return { field: fieldName, message: 'Password must be at least 12 characters' };
|
|
}
|
|
const hasUpper = /[A-Z]/.test(password);
|
|
const hasLower = /[a-z]/.test(password);
|
|
const hasDigit = /\d/.test(password);
|
|
const hasSpecial = /[^A-Za-z0-9]/.test(password);
|
|
const classCount = [hasUpper, hasLower, hasDigit, hasSpecial].filter(Boolean).length;
|
|
if (classCount < 3) {
|
|
return { field: fieldName, message: 'Password must include at least 3 of: uppercase, lowercase, number, special character' };
|
|
}
|
|
return null;
|
|
}
|
|
export function validateUsername(username) {
|
|
if (!username.trim()) {
|
|
return { field: 'username', message: 'Username is required' };
|
|
}
|
|
if (username.length < 3) {
|
|
return { field: 'username', message: 'Username must be at least 3 characters' };
|
|
}
|
|
if (username.length > 30) {
|
|
return { field: 'username', message: 'Username must be 30 characters or less' };
|
|
}
|
|
if (!USERNAME_REGEX.test(username)) {
|
|
return { field: 'username', message: 'Username can only contain letters, numbers, dots, underscores, and hyphens' };
|
|
}
|
|
return null;
|
|
}
|
|
export function validateConfirmPassword(password, confirmPassword) {
|
|
if (!confirmPassword) {
|
|
return { field: 'confirmPassword', message: 'Please confirm your password' };
|
|
}
|
|
if (password !== confirmPassword) {
|
|
return { field: 'confirmPassword', message: 'Passwords do not match' };
|
|
}
|
|
return null;
|
|
}
|
|
export function validateLoginForm(credentials) {
|
|
const errors = [];
|
|
const emailError = validateEmail(credentials.email);
|
|
if (emailError)
|
|
errors.push(emailError);
|
|
const passwordError = validatePassword(credentials.password);
|
|
if (passwordError)
|
|
errors.push(passwordError);
|
|
return {
|
|
valid: errors.length === 0,
|
|
errors,
|
|
};
|
|
}
|
|
export function validateRegisterForm(credentials) {
|
|
const errors = [];
|
|
const emailError = validateEmail(credentials.email);
|
|
if (emailError)
|
|
errors.push(emailError);
|
|
// Username is optional — auto-derived from email when empty
|
|
if (credentials.username?.trim()) {
|
|
const usernameError = validateUsername(credentials.username);
|
|
if (usernameError)
|
|
errors.push(usernameError);
|
|
}
|
|
const passwordError = validatePassword(credentials.password);
|
|
if (passwordError)
|
|
errors.push(passwordError);
|
|
if (credentials.confirmPassword !== undefined) {
|
|
const confirmError = validateConfirmPassword(credentials.password, credentials.confirmPassword);
|
|
if (confirmError)
|
|
errors.push(confirmError);
|
|
}
|
|
// Terms validation
|
|
if (credentials.termsAccepted === false) {
|
|
errors.push({ field: 'terms', message: 'You must agree to the terms and conditions' });
|
|
}
|
|
return {
|
|
valid: errors.length === 0,
|
|
errors,
|
|
};
|
|
}
|
|
export function getFieldError(errors, fieldName) {
|
|
return errors.find(e => e.field === fieldName)?.message;
|
|
}
|
|
//# sourceMappingURL=validation.js.map
|