55 lines
1.8 KiB
JavaScript
55 lines
1.8 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Shared validation for user account fields.
|
|
* Email is MANDATORY on every account: it is how approval notifications and
|
|
* system messages reach people, so an account without one cannot function.
|
|
*/
|
|
|
|
const EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
|
|
const USERNAME_RE = /^[A-Za-z0-9._-]{3,32}$/;
|
|
|
|
/**
|
|
* Normalise an email for storage: trim surrounding whitespace.
|
|
* Returns '' for null/undefined so callers can treat "missing" and "blank"
|
|
* the same way.
|
|
*/
|
|
function normaliseEmail(value) {
|
|
return value === undefined || value === null ? '' : String(value).trim();
|
|
}
|
|
|
|
/**
|
|
* Validate a mandatory email address.
|
|
* @returns {string|null} an error message, or null when valid.
|
|
*/
|
|
function validateEmail(value) {
|
|
const email = normaliseEmail(value);
|
|
if (!email) return 'An email address is required.';
|
|
if (email.length > 254) return 'That email address is too long.';
|
|
if (!EMAIL_RE.test(email)) return 'Please enter a valid email address.';
|
|
return null;
|
|
}
|
|
|
|
function validateUsername(value) {
|
|
const username = value === undefined || value === null ? '' : String(value).trim();
|
|
if (!username) return 'A username is required.';
|
|
if (!USERNAME_RE.test(username)) {
|
|
return 'Username must be 3-32 characters: letters, numbers, dot, underscore or hyphen.';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function validatePassword(value) {
|
|
const password = value === undefined || value === null ? '' : String(value);
|
|
if (!password) return 'A password is required.';
|
|
if (password.length < 10) return 'Password must be at least 10 characters long.';
|
|
if (!/[A-Za-z]/.test(password) || !/[0-9]/.test(password)) {
|
|
return 'Password must contain at least one letter and one number.';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
module.exports = {
|
|
EMAIL_RE, USERNAME_RE, normaliseEmail, validateEmail, validateUsername, validatePassword,
|
|
};
|