Moved validation methods into the new Users class.
This commit is contained in:
parent
07a2868159
commit
f03c8ebfa5
7 changed files with 219 additions and 202 deletions
|
@ -64,8 +64,9 @@ while($canResetPassword) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(User::validatePassword($passwordNew) !== '') {
|
$passwordValidation = $users->validatePassword($passwordNew);
|
||||||
$notices[] = 'Your password is too weak!';
|
if($passwordValidation !== '') {
|
||||||
|
$notices[] = $users->validatePasswordText($passwordValidation);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,21 +65,20 @@ while(!$restricted && !empty($register)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$usernameValidation = User::validateUsername($register['username']);
|
$usernameValidation = $users->validateName($register['username']);
|
||||||
if($usernameValidation !== '')
|
if($usernameValidation !== '')
|
||||||
$notices[] = User::usernameValidationErrorString($usernameValidation);
|
$notices[] = $users->validateNameText($usernameValidation);
|
||||||
|
|
||||||
$emailValidation = User::validateEMailAddress($register['email']);
|
$emailValidation = $users->validateEMailAddress($register['email']);
|
||||||
if($emailValidation !== '')
|
if($emailValidation !== '')
|
||||||
$notices[] = $emailValidation === 'in-use'
|
$notices[] = $users->validateEMailAddressText($emailValidation);
|
||||||
? 'This e-mail address has already been used!'
|
|
||||||
: 'The e-mail address you entered is invalid!';
|
|
||||||
|
|
||||||
if($register['password_confirm'] !== $register['password'])
|
if($register['password_confirm'] !== $register['password'])
|
||||||
$notices[] = 'The given passwords don\'t match.';
|
$notices[] = 'The given passwords don\'t match.';
|
||||||
|
|
||||||
if(User::validatePassword($register['password']) !== '')
|
$passwordValidation = $users->validatePassword($register['password']);
|
||||||
$notices[] = 'Your password is too weak!';
|
if($passwordValidation !== '')
|
||||||
|
$notices[] = $users->validatePasswordText($passwordValidation);
|
||||||
|
|
||||||
if(!empty($notices))
|
if(!empty($notices))
|
||||||
break;
|
break;
|
||||||
|
@ -102,6 +101,7 @@ while(!$restricted && !empty($register)) {
|
||||||
|
|
||||||
$users->addRoles($userInfo, $defaultRoleInfo);
|
$users->addRoles($userInfo, $defaultRoleInfo);
|
||||||
$config->setString('users.newest', $userInfo->getId());
|
$config->setString('users.newest', $userInfo->getId());
|
||||||
|
$config->setBoolean('perms.needsRecalc', true);
|
||||||
|
|
||||||
url_redirect('auth-login-welcome', ['username' => $userInfo->getName()]);
|
url_redirect('auth-login-welcome', ['username' => $userInfo->getName()]);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -194,9 +194,13 @@ if(CSRF::validateRequest() && $canEdit) {
|
||||||
if(!empty($passwordNewValue)) {
|
if(!empty($passwordNewValue)) {
|
||||||
if($passwordNewValue !== $passwordConfirmValue)
|
if($passwordNewValue !== $passwordConfirmValue)
|
||||||
$notices[] = 'Confirm password does not match.';
|
$notices[] = 'Confirm password does not match.';
|
||||||
elseif(!empty(User::validatePassword($passwordNewValue)))
|
else {
|
||||||
$notices[] = 'New password is too weak.';
|
$passwordValidation = $users->validatePassword($passwordNewValue);
|
||||||
else
|
if($passwordValidation !== '')
|
||||||
|
$notices[] = $users->validatePasswordText($passwordValidation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($notices))
|
||||||
$users->updateUser(userInfo: $userInfo, password: $passwordNewValue);
|
$users->updateUser(userInfo: $userInfo, password: $passwordNewValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,21 +144,12 @@ if($isEditing) {
|
||||||
} else {
|
} else {
|
||||||
$aboutText = (string)($_POST['about']['text'] ?? '');
|
$aboutText = (string)($_POST['about']['text'] ?? '');
|
||||||
$aboutParse = (int)($_POST['about']['parser'] ?? Parser::PLAIN);
|
$aboutParse = (int)($_POST['about']['parser'] ?? Parser::PLAIN);
|
||||||
$aboutValid = User::validateProfileAbout($aboutParse, $aboutText);
|
$aboutValid = $users->validateProfileAbout($aboutParse, $aboutText);
|
||||||
|
|
||||||
if($aboutValid === '')
|
if($aboutValid === '')
|
||||||
$users->updateUser($userInfo, aboutContent: $aboutText, aboutParser: $aboutParse);
|
$users->updateUser($userInfo, aboutContent: $aboutText, aboutParser: $aboutParse);
|
||||||
else switch($aboutValid) {
|
else
|
||||||
case 'parser':
|
$notices[] = $users->validateProfileAboutText($aboutValid);
|
||||||
$notices[] = 'The selected about section parser is invalid.';
|
|
||||||
break;
|
|
||||||
case 'long':
|
|
||||||
$notices[] = sprintf('Please keep the length of your about section below %d characters.', User::PROFILE_ABOUT_MAX_LENGTH);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$notices[] = 'Failed to update about section, contact an administator.';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,21 +159,12 @@ if($isEditing) {
|
||||||
} else {
|
} else {
|
||||||
$sigText = (string)($_POST['signature']['text'] ?? '');
|
$sigText = (string)($_POST['signature']['text'] ?? '');
|
||||||
$sigParse = (int)($_POST['signature']['parser'] ?? Parser::PLAIN);
|
$sigParse = (int)($_POST['signature']['parser'] ?? Parser::PLAIN);
|
||||||
$sigValid = User::validateForumSignature($sigParse, $sigText);
|
$sigValid = $users->validateForumSignature($sigParse, $sigText);
|
||||||
|
|
||||||
if($sigValid === '')
|
if($sigValid === '')
|
||||||
$users->updateUser($userInfo, signatureContent: $sigText, signatureParser: $sigParse);
|
$users->updateUser($userInfo, signatureContent: $sigText, signatureParser: $sigParse);
|
||||||
else switch($sigValid) {
|
else
|
||||||
case 'parser':
|
$notices[] = $users->validateForumSignatureText($sigValid);
|
||||||
$notices[] = 'The selected forum signature parser is invalid.';
|
|
||||||
break;
|
|
||||||
case 'long':
|
|
||||||
$notices[] = sprintf('Please keep the length of your signature below %d characters.', User::FORUM_SIGNATURE_MAX_LENGTH);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$notices[] = 'Failed to update signature, contact an administator.';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,21 +175,12 @@ if($isEditing) {
|
||||||
$birthYear = (int)($_POST['birthdate']['year'] ?? 0);
|
$birthYear = (int)($_POST['birthdate']['year'] ?? 0);
|
||||||
$birthMonth = (int)($_POST['birthdate']['month'] ?? 0);
|
$birthMonth = (int)($_POST['birthdate']['month'] ?? 0);
|
||||||
$birthDay = (int)($_POST['birthdate']['day'] ?? 0);
|
$birthDay = (int)($_POST['birthdate']['day'] ?? 0);
|
||||||
$birthValid = User::validateBirthdate($birthYear, $birthMonth, $birthDay);
|
$birthValid = $users->validateBirthdate($birthYear, $birthMonth, $birthDay);
|
||||||
|
|
||||||
if($birthValid === '')
|
if($birthValid === '')
|
||||||
$users->updateUser($userInfo, birthYear: $birthYear, birthMonth: $birthMonth, birthDay: $birthDay);
|
$users->updateUser($userInfo, birthYear: $birthYear, birthMonth: $birthMonth, birthDay: $birthDay);
|
||||||
else switch($birthValid) {
|
else
|
||||||
case 'year':
|
$notices[] = $users->validateBirthdateText($birthValid);
|
||||||
$notices[] = 'The given birth year is invalid.';
|
|
||||||
break;
|
|
||||||
case 'date':
|
|
||||||
$notices[] = 'The given birthdate is invalid.';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$notices[] = 'Something unexpected happened while setting your birthdate.';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,25 +80,10 @@ if($isVerifiedRequest && !empty($_POST['current_password'])) {
|
||||||
} elseif($userInfo->getEMailAddress() === mb_strtolower($_POST['email']['confirm'])) {
|
} elseif($userInfo->getEMailAddress() === mb_strtolower($_POST['email']['confirm'])) {
|
||||||
$errors[] = 'This is already your e-mail address!';
|
$errors[] = 'This is already your e-mail address!';
|
||||||
} else {
|
} else {
|
||||||
$checkMail = User::validateEMailAddress($_POST['email']['new'], true);
|
$checkMail = $users->validateEMailAddress($_POST['email']['new']);
|
||||||
|
|
||||||
if($checkMail !== '') {
|
if($checkMail !== '') {
|
||||||
switch($checkMail) {
|
$errors[] = $users->validateEMailAddressText($checkMail);
|
||||||
case 'dns':
|
|
||||||
$errors[] = 'No valid MX record exists for this domain.';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'format':
|
|
||||||
$errors[] = 'The given e-mail address was incorrectly formatted.';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'in-use':
|
|
||||||
$errors[] = 'This e-mail address is already in use.';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$errors[] = 'Unknown e-mail validation error.';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$users->updateUser(userInfo: $userInfo, emailAddr: $_POST['email']['new']);
|
$users->updateUser(userInfo: $userInfo, emailAddr: $_POST['email']['new']);
|
||||||
$msz->createAuditLog('PERSONAL_EMAIL_CHANGE', [$_POST['email']['new']]);
|
$msz->createAuditLog('PERSONAL_EMAIL_CHANGE', [$_POST['email']['new']]);
|
||||||
|
@ -111,10 +96,10 @@ if($isVerifiedRequest && !empty($_POST['current_password'])) {
|
||||||
if(empty($_POST['password']['confirm']) || $_POST['password']['new'] !== $_POST['password']['confirm']) {
|
if(empty($_POST['password']['confirm']) || $_POST['password']['new'] !== $_POST['password']['confirm']) {
|
||||||
$errors[] = 'The new passwords you entered did not match each other.';
|
$errors[] = 'The new passwords you entered did not match each other.';
|
||||||
} else {
|
} else {
|
||||||
$checkPassword = User::validatePassword($_POST['password']['new']);
|
$checkPassword = $users->validatePassword($_POST['password']['new']);
|
||||||
|
|
||||||
if($checkPassword !== '') {
|
if($checkPassword !== '') {
|
||||||
$errors[] = 'The given passwords was too weak.';
|
$errors[] = $users->validatePasswordText($checkPassword);
|
||||||
} else {
|
} else {
|
||||||
$users->updateUser(userInfo: $userInfo, password: $_POST['password']['new']);
|
$users->updateUser(userInfo: $userInfo, password: $_POST['password']['new']);
|
||||||
$msz->createAuditLog('PERSONAL_PASSWORD_CHANGE');
|
$msz->createAuditLog('PERSONAL_PASSWORD_CHANGE');
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Misuzu\Users;
|
|
||||||
|
|
||||||
use Index\XString;
|
|
||||||
use Misuzu\DateCheck;
|
|
||||||
use Misuzu\DB;
|
|
||||||
use Misuzu\Parsers\Parser;
|
|
||||||
|
|
||||||
class User {
|
|
||||||
public const NAME_MIN_LENGTH = 3; // Minimum username length
|
|
||||||
public const NAME_MAX_LENGTH = 16; // Maximum username length, unless your name is Flappyzor(WorldwideOnline2018through2019through2020)
|
|
||||||
public const NAME_REGEX = '[A-Za-z0-9-_]+'; // Username character constraint
|
|
||||||
|
|
||||||
// Minimum amount of unique characters for passwords
|
|
||||||
public const PASSWORD_UNIQUE = 6;
|
|
||||||
|
|
||||||
// Maximum length of profile about section
|
|
||||||
public const PROFILE_ABOUT_MAX_LENGTH = 50000;
|
|
||||||
|
|
||||||
// Maximum length of forum signature
|
|
||||||
public const FORUM_SIGNATURE_MAX_LENGTH = 2000;
|
|
||||||
|
|
||||||
public static function validateUsername(string $name): string {
|
|
||||||
if($name !== trim($name))
|
|
||||||
return 'trim';
|
|
||||||
|
|
||||||
if(str_starts_with(mb_strtolower($name), 'flappyzor'))
|
|
||||||
return 'flapp';
|
|
||||||
|
|
||||||
$length = mb_strlen($name);
|
|
||||||
if($length < self::NAME_MIN_LENGTH)
|
|
||||||
return 'short';
|
|
||||||
if($length > self::NAME_MAX_LENGTH)
|
|
||||||
return 'long';
|
|
||||||
|
|
||||||
if(!preg_match('#^' . self::NAME_REGEX . '$#u', $name))
|
|
||||||
return 'invalid';
|
|
||||||
|
|
||||||
$userId = (int)DB::prepare('SELECT user_id FROM msz_users WHERE username = :username')
|
|
||||||
->bind('username', $name)->fetchColumn();
|
|
||||||
if($userId > 0)
|
|
||||||
return 'in-use';
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function usernameValidationErrorString(string $error): string {
|
|
||||||
switch($error) {
|
|
||||||
case 'trim':
|
|
||||||
return 'Your username may not start or end with spaces!';
|
|
||||||
case 'short':
|
|
||||||
return sprintf('Your username is too short, it has to be at least %d characters!', self::NAME_MIN_LENGTH);
|
|
||||||
case 'long':
|
|
||||||
return sprintf("Your username is too long, it can't be longer than %d characters!", self::NAME_MAX_LENGTH);
|
|
||||||
case 'invalid':
|
|
||||||
return 'Your username contains invalid characters.';
|
|
||||||
case 'in-use':
|
|
||||||
return 'This username is already taken!';
|
|
||||||
case 'flapp':
|
|
||||||
return 'Your username may not start with Flappyzor!';
|
|
||||||
case '':
|
|
||||||
return 'This username is correctly formatted!';
|
|
||||||
default:
|
|
||||||
return 'This username is incorrectly formatted.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateEMailAddress(string $address): string {
|
|
||||||
if(filter_var($address, FILTER_VALIDATE_EMAIL) === false)
|
|
||||||
return 'format';
|
|
||||||
if(!checkdnsrr(mb_substr(mb_strstr($address, '@'), 1), 'MX'))
|
|
||||||
return 'dns';
|
|
||||||
|
|
||||||
$userId = (int)DB::prepare('SELECT user_id FROM msz_users WHERE email = :email')
|
|
||||||
->bind('email', $address)->fetchColumn();
|
|
||||||
if($userId > 0)
|
|
||||||
return 'in-use';
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validatePassword(string $password): string {
|
|
||||||
if(XString::countUnique($password) < self::PASSWORD_UNIQUE)
|
|
||||||
return 'weak';
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateBirthdate(int $year, int $month, int $day, int $yearRange = 100): string {
|
|
||||||
if($day !== 0 && $month !== 0) {
|
|
||||||
if($year > 0 && ($year < date('Y') - $yearRange || $year > date('Y')))
|
|
||||||
return 'year';
|
|
||||||
|
|
||||||
if(!DateCheck::isValidDate($year, $month, $day))
|
|
||||||
return 'date';
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateProfileAbout(int $parser, string $text): string {
|
|
||||||
if(!Parser::isValid($parser))
|
|
||||||
return 'parser';
|
|
||||||
|
|
||||||
$length = strlen($text);
|
|
||||||
if($length > self::PROFILE_ABOUT_MAX_LENGTH)
|
|
||||||
return 'long';
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateForumSignature(int $parser, string $text): string {
|
|
||||||
if(!Parser::isValid($parser))
|
|
||||||
return 'parser';
|
|
||||||
|
|
||||||
$length = strlen($text);
|
|
||||||
if($length > self::FORUM_SIGNATURE_MAX_LENGTH)
|
|
||||||
return 'long';
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,12 +4,15 @@ namespace Misuzu\Users;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Index\DateTime;
|
use Index\DateTime;
|
||||||
|
use Index\XString;
|
||||||
use Index\Colour\Colour;
|
use Index\Colour\Colour;
|
||||||
use Index\Data\DbStatementCache;
|
use Index\Data\DbStatementCache;
|
||||||
use Index\Data\DbTools;
|
use Index\Data\DbTools;
|
||||||
use Index\Data\IDbConnection;
|
use Index\Data\IDbConnection;
|
||||||
use Index\Net\IPAddress;
|
use Index\Net\IPAddress;
|
||||||
|
use Misuzu\DateCheck;
|
||||||
use Misuzu\Pagination;
|
use Misuzu\Pagination;
|
||||||
|
use Misuzu\Parsers\Parser;
|
||||||
|
|
||||||
class Users {
|
class Users {
|
||||||
private IDbConnection $dbConn;
|
private IDbConnection $dbConn;
|
||||||
|
@ -20,8 +23,15 @@ class Users {
|
||||||
$this->cache = new DbStatementCache($dbConn);
|
$this->cache = new DbStatementCache($dbConn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const PASSWORD_ALGO = PASSWORD_ARGON2ID;
|
public const NAME_MIN_LENGTH = 3;
|
||||||
private const PASSWORD_OPTS = [];
|
public const NAME_MAX_LENGTH = 16;
|
||||||
|
|
||||||
|
public const PASSWORD_ALGO = PASSWORD_ARGON2ID;
|
||||||
|
public const PASSWORD_OPTS = [];
|
||||||
|
public const PASSWORD_UNIQUE = 6;
|
||||||
|
|
||||||
|
public const PROFILE_ABOUT_MAX_LENGTH = 50000;
|
||||||
|
public const FORUM_SIGNATURE_MAX_LENGTH = 2000;
|
||||||
|
|
||||||
public static function passwordHash(string $password): string {
|
public static function passwordHash(string $password): string {
|
||||||
return password_hash($password, self::PASSWORD_ALGO, self::PASSWORD_OPTS);
|
return password_hash($password, self::PASSWORD_ALGO, self::PASSWORD_OPTS);
|
||||||
|
@ -254,7 +264,10 @@ class Users {
|
||||||
|
|
||||||
$password = self::passwordHash($password);
|
$password = self::passwordHash($password);
|
||||||
|
|
||||||
// todo: validation
|
if(self::validateName($name, true) !== '')
|
||||||
|
throw new InvalidArgumentException('$name is not a valid user name.');
|
||||||
|
if(self::validateEMailAddress($email, true) !== '')
|
||||||
|
throw new InvalidArgumentException('$email is not a valid e-mail address.');
|
||||||
|
|
||||||
$stmt = $this->cache->get('INSERT INTO msz_users (username, password, email, register_ip, last_ip, user_country, display_role) VALUES (?, ?, ?, INET6_ATON(?), INET6_ATON(?), ?, ?)');
|
$stmt = $this->cache->get('INSERT INTO msz_users (username, password, email, register_ip, last_ip, user_country, display_role) VALUES (?, ?, ?, INET6_ATON(?), INET6_ATON(?), ?, ?)');
|
||||||
$stmt->addParameter(1, $name);
|
$stmt->addParameter(1, $name);
|
||||||
|
@ -293,16 +306,21 @@ class Users {
|
||||||
if($displayRoleInfo instanceof RoleInfo)
|
if($displayRoleInfo instanceof RoleInfo)
|
||||||
$displayRoleInfo = $displayRoleInfo->getId();
|
$displayRoleInfo = $displayRoleInfo->getId();
|
||||||
|
|
||||||
// do sanity checks on values at some point lol
|
|
||||||
$fields = [];
|
$fields = [];
|
||||||
$values = [];
|
$values = [];
|
||||||
|
|
||||||
if($name !== null) {
|
if($name !== null) {
|
||||||
|
if(self::validateName($name, true) !== '')
|
||||||
|
throw new InvalidArgumentException('$name is not valid.');
|
||||||
|
|
||||||
$fields[] = 'username = ?';
|
$fields[] = 'username = ?';
|
||||||
$values[] = $name;
|
$values[] = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($emailAddr !== null) {
|
if($emailAddr !== null) {
|
||||||
|
if(self::validateEMailAddress($emailAddr, true) !== '')
|
||||||
|
throw new InvalidArgumentException('$emailAddr is not valid.');
|
||||||
|
|
||||||
$fields[] = 'email = ?';
|
$fields[] = 'email = ?';
|
||||||
$values[] = $emailAddr;
|
$values[] = $emailAddr;
|
||||||
}
|
}
|
||||||
|
@ -332,27 +350,30 @@ class Users {
|
||||||
$values[] = $totpKey === '' ? null : $totpKey;
|
$values[] = $totpKey === '' ? null : $totpKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($aboutContent !== null) {
|
if($aboutContent !== null && $aboutParser !== null) {
|
||||||
|
if(self::validateProfileAbout($aboutParser, $aboutContent) !== '')
|
||||||
|
throw new InvalidArgumentException('$aboutContent and $aboutParser contain invalid data!');
|
||||||
|
|
||||||
$fields[] = 'user_about_content = ?';
|
$fields[] = 'user_about_content = ?';
|
||||||
$values[] = $aboutContent;
|
$values[] = $aboutContent;
|
||||||
}
|
|
||||||
|
|
||||||
if($aboutParser !== null) {
|
|
||||||
$fields[] = 'user_about_parser = ?';
|
$fields[] = 'user_about_parser = ?';
|
||||||
$values[] = $aboutParser;
|
$values[] = $aboutParser;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($signatureContent !== null) {
|
if($signatureContent !== null && $signatureParser !== null) {
|
||||||
|
if(self::validateForumSignature($signatureParser, $signatureContent) !== '')
|
||||||
|
throw new InvalidArgumentException('$signatureContent and $signatureParser contain invalid data!');
|
||||||
|
|
||||||
$fields[] = 'user_signature_content = ?';
|
$fields[] = 'user_signature_content = ?';
|
||||||
$values[] = $signatureContent;
|
$values[] = $signatureContent;
|
||||||
}
|
|
||||||
|
|
||||||
if($signatureParser !== null) {
|
|
||||||
$fields[] = 'user_signature_parser = ?';
|
$fields[] = 'user_signature_parser = ?';
|
||||||
$values[] = $signatureParser;
|
$values[] = $signatureParser;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($birthMonth !== null && $birthDay !== null) {
|
if($birthMonth !== null && $birthDay !== null) {
|
||||||
|
if(self::validateBirthdate($birthYear, $birthMonth, $birthDay) !== '')
|
||||||
|
throw new InvalidArgumentException('$birthYear, $birthMonth and $birthDay contain invalid data!');
|
||||||
|
|
||||||
// lowest leap year MariaDB accepts, used a 'no year' value
|
// lowest leap year MariaDB accepts, used a 'no year' value
|
||||||
if($birthYear < 1004)
|
if($birthYear < 1004)
|
||||||
$birthYear = 1004;
|
$birthYear = 1004;
|
||||||
|
@ -541,4 +562,159 @@ class Users {
|
||||||
$result = $stmt->getResult();
|
$result = $stmt->getResult();
|
||||||
return $result->next() ? $result->getInteger(0) : 0;
|
return $result->next() ? $result->getInteger(0) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function checkNameInUse(string $name): bool {
|
||||||
|
$stmt = $this->cache->get('SELECT COUNT(*) FROM msz_users WHERE username = ?');
|
||||||
|
$stmt->addParameter(1, $name);
|
||||||
|
$stmt->execute();
|
||||||
|
$result = $stmt->getResult();
|
||||||
|
if(!$result->next())
|
||||||
|
throw new RuntimeException('Was not able to check if name is already in use.');
|
||||||
|
return $result->getInteger(0) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateName(string $name, bool $skipInUse = false): string {
|
||||||
|
if($name !== trim($name))
|
||||||
|
return 'trim';
|
||||||
|
|
||||||
|
if(str_starts_with(mb_strtolower($name), 'flappyzor'))
|
||||||
|
return 'flapp';
|
||||||
|
|
||||||
|
$length = mb_strlen($name);
|
||||||
|
if($length < self::NAME_MIN_LENGTH)
|
||||||
|
return 'short';
|
||||||
|
if($length > self::NAME_MAX_LENGTH)
|
||||||
|
return 'long';
|
||||||
|
|
||||||
|
if(!preg_match('#^[A-Za-z0-9-_]+$#u', $name))
|
||||||
|
return 'invalid';
|
||||||
|
|
||||||
|
if(!$skipInUse && $this->checkNameInUse($name))
|
||||||
|
return 'used';
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validateNameText(string $error): string {
|
||||||
|
return match($error) {
|
||||||
|
'trim' => 'Your username may not start or end with spaces.',
|
||||||
|
'short' => sprintf('Your username is too short, it has to be at least %d characters.', self::NAME_MIN_LENGTH),
|
||||||
|
'long' => sprintf("Your username is too long, it can't be longer than %d characters.", self::NAME_MAX_LENGTH),
|
||||||
|
'invalid' => 'Your username contains invalid characters.',
|
||||||
|
'used' => 'That username is already taken.',
|
||||||
|
'flapp' => 'Your username may not start with Flappyzor.',
|
||||||
|
'' => 'Your username is correctly formatted, why are you seeing this?',
|
||||||
|
default => 'This username is incorrectly formatted.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkEMailAddressInUse(string $address): bool {
|
||||||
|
$stmt = $this->cache->get('SELECT COUNT(*) FROM msz_users WHERE email = ?');
|
||||||
|
$stmt->addParameter(1, $address);
|
||||||
|
$stmt->execute();
|
||||||
|
$result = $stmt->getResult();
|
||||||
|
if(!$result->next())
|
||||||
|
throw new RuntimeException('Was not able to check if e-mail address is already in use.');
|
||||||
|
return $result->getInteger(0) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateEMailAddress(string $address, bool $skipInUse = false): string {
|
||||||
|
if(filter_var($address, FILTER_VALIDATE_EMAIL) === false)
|
||||||
|
return 'invalid';
|
||||||
|
|
||||||
|
if(!checkdnsrr(mb_substr(mb_strstr($address, '@'), 1), 'MX'))
|
||||||
|
return 'dns';
|
||||||
|
|
||||||
|
if(!$skipInUse && $this->checkEMailAddressInUse($address))
|
||||||
|
return 'used';
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validateEMailAddressText(string $error): string {
|
||||||
|
return match($error) {
|
||||||
|
'dns' => 'Was unable to find a mail server running on the domain in your e-mail address.',
|
||||||
|
'' => 'Your e-mail address is correctly formatted, why are you seeing this?',
|
||||||
|
default => 'Your e-mail address is not correctly formatted.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validatePassword(string $password): string {
|
||||||
|
if(XString::countUnique($password) < self::PASSWORD_UNIQUE)
|
||||||
|
return 'weak';
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validatePasswordText(string $error): string {
|
||||||
|
return match($error) {
|
||||||
|
'weak' => sprintf("Your password is too weak, it must contain at least %d unique characters.", self::PASSWORD_UNIQUE),
|
||||||
|
'' => 'Your password is strong enough, why are you seeing this?',
|
||||||
|
default => 'Your password is not acceptable.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validateBirthdate(?int $year, int $month, int $day, int $yearRange = 100): string {
|
||||||
|
$year ??= 0;
|
||||||
|
|
||||||
|
if($day !== 0 && $month !== 0) {
|
||||||
|
$currentYear = (int)date('Y');
|
||||||
|
if($year > 0 && ($year < $currentYear - $yearRange || $year > $currentYear))
|
||||||
|
return 'year';
|
||||||
|
|
||||||
|
if(!DateCheck::isValidDate($year, $month, $day))
|
||||||
|
return 'date';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validateBirthdateText(string $error): string {
|
||||||
|
return match($error) {
|
||||||
|
'year' => 'The year in your birthdate is too ridiculous.',
|
||||||
|
'date' => 'The birthdate you attempted to set is not a valid date.',
|
||||||
|
'' => 'Your birthdate is fine, why are you seeing this?',
|
||||||
|
default => 'Your birthdate is not acceptable.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validateProfileAbout(int $parser, string $text): string {
|
||||||
|
if(!Parser::isValid($parser))
|
||||||
|
return 'parser';
|
||||||
|
|
||||||
|
$length = strlen($text);
|
||||||
|
if($length > self::PROFILE_ABOUT_MAX_LENGTH)
|
||||||
|
return 'long';
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validateProfileAboutText(string $error): string {
|
||||||
|
return match($error) {
|
||||||
|
'parser' => 'You attempted to select an invalid parser for your profile about section.',
|
||||||
|
'long' => sprintf('Please keep the length of your profile about section below %d characters.', self::PROFILE_ABOUT_MAX_LENGTH),
|
||||||
|
'' => 'Your profile about section is fine, why are you seeing this?',
|
||||||
|
default => 'Your profile about section is not acceptable.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validateForumSignature(int $parser, string $text): string {
|
||||||
|
if(!Parser::isValid($parser))
|
||||||
|
return 'parser';
|
||||||
|
|
||||||
|
$length = strlen($text);
|
||||||
|
if($length > self::FORUM_SIGNATURE_MAX_LENGTH)
|
||||||
|
return 'long';
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function validateForumSignatureText(string $error): string {
|
||||||
|
return match($error) {
|
||||||
|
'parser' => 'You attempted to select an invalid parser for your forum signature.',
|
||||||
|
'long' => sprintf('Please keep the length of your forum signature below %d characters.', self::FORUM_SIGNATURE_MAX_LENGTH),
|
||||||
|
'' => 'Your forum signature is fine, why are you seeing this?',
|
||||||
|
default => 'Your forum signature is not acceptable.',
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue