Files
2026-09-13 20:10:17 +01:00

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,
};