Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix User Date of Birth Validation and Processing #16620

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions core/src/Revolution/Processors/Security/Profile/Update.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/*
* This file is part of MODX Revolution.
*
Expand All @@ -10,10 +11,9 @@

namespace MODX\Revolution\Processors\Security\Profile;


use MODX\Revolution\Processors\Processor;
use MODX\Revolution\modUser;
use MODX\Revolution\modUserProfile;
use MODX\Revolution\Processors\Processor;

/**
* Update a user profile
Expand Down Expand Up @@ -49,7 +49,6 @@ public function initialize()
if ($this->profile === null) {
return $this->modx->lexicon('user_profile_err_not_found');
}

return true;
}

Expand Down Expand Up @@ -96,12 +95,19 @@ public function prepare()
/* format and set data */
$dob = $this->getProperty('dob');
if (!empty($dob)) {
$properties['dob'] = strtotime($dob);
$date = \DateTimeImmutable::createFromFormat($this->modx->getOption('manager_date_format', null, 'Y-m-d', true), $dob);
if ($date === false) {
$this->addFieldError('dob', $this->modx->lexicon('user_err_not_specified_dob'));
} else {
$properties['dob'] = $date->getTimestamp();
}
}

$this->profile->fromArray($properties);
}

public function validate() {
public function validate()
{
if ($this->getProperty('newpassword') !== 'false') {
$oldPassword = $this->getProperty('password_old');
$newPassword = $this->getProperty('password_new');
Expand All @@ -113,10 +119,10 @@ public function validate() {
}
if (empty($newPassword) || strlen($newPassword) < $this->modx->getOption('password_min_length', null, 8)) {
$this->addFieldError('password_new', $this->modx->lexicon('user_err_password_too_short'));
} else if (!preg_match('/^[^\'\x3c\x3e\(\);\x22\x7b\x7d\x2f\x5c]+$/', $newPassword)) {
} elseif (!preg_match('/^[^\'\x3c\x3e\(\);\x22\x7b\x7d\x2f\x5c]+$/', $newPassword)) {
$this->addFieldError('password_new', $this->modx->lexicon('user_err_password_invalid'));
}
if (empty($confirmPassword) || strcmp($newPassword,$confirmPassword) != 0) {
if (empty($confirmPassword) || strcmp($newPassword, $confirmPassword) != 0) {
$this->addFieldError('password_confirm', $this->modx->lexicon('user_err_password_no_match'));
}
}
Expand Down
139 changes: 75 additions & 64 deletions core/src/Revolution/Processors/Security/User/Validation.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/*
* This file is part of the MODX Revolution package.
*
Expand All @@ -10,18 +11,18 @@

namespace MODX\Revolution\Processors\Security\User;


use MODX\Revolution\Processors\ModelProcessor;
use MODX\Revolution\modUser;
use MODX\Revolution\modUserProfile;
use MODX\Revolution\modX;
use MODX\Revolution\Processors\ModelProcessor;

/**
* Handles common validation for user processors
*
* @package MODX\Revolution\Processors\Security\User
*/
class Validation {
class Validation
{
/** @var modX $modx */
public $modx;
/** @var Create|Update $processor */
Expand All @@ -31,14 +32,16 @@ class Validation {
/** @var modUserProfile $profile */
public $profile;

function __construct(ModelProcessor &$processor,modUser &$user,modUserProfile &$profile) {
public function __construct(ModelProcessor &$processor, modUser &$user, modUserProfile &$profile)
{
$this->processor =& $processor;
$this->modx =& $processor->modx;
$this->user =& $user;
$this->profile =& $profile;
}

public function validate() {
public function validate()
{
$this->checkUsername();
$this->checkPassword();
$this->checkEmail();
Expand All @@ -50,146 +53,154 @@ public function validate() {
return !$this->processor->hasErrors();
}

public function checkUsername() {
public function checkUsername()
{
$username = $this->processor->getProperty('username');
if (empty($username)) {
$this->processor->addFieldError('username',$this->modx->lexicon('user_err_not_specified_username'));
$this->processor->addFieldError('username', $this->modx->lexicon('user_err_not_specified_username'));
} elseif (!preg_match('/^[^\'\\x3c\\x3e\\(\\);\\x22]+$/', $username)) {
$this->processor->addFieldError('username',$this->modx->lexicon('user_err_username_invalid'));
} else if (!empty($username)) {
$this->processor->addFieldError('username', $this->modx->lexicon('user_err_username_invalid'));
} elseif (!empty($username)) {
if ($this->alreadyExists($username)) {
$this->processor->addFieldError('username',$this->modx->lexicon('user_err_already_exists'));
$this->processor->addFieldError('username', $this->modx->lexicon('user_err_already_exists'));
}
$this->user->set('username',$username);
$this->user->set('username', $username);
}
}

public function alreadyExists($name) {
return $this->modx->getCount(modUser::class,
[
public function alreadyExists($name)
{
return $this->modx->getCount(
modUser::class,
[
'username' => $name,
'id:!=' => $this->user->get('id'),
]
) > 0;
) > 0;
}

public function checkPassword() {
$newPassword = $this->processor->getProperty('newpassword',null);
public function checkPassword()
{
$newPassword = $this->processor->getProperty('newpassword', null);
$id = $this->processor->getProperty('id');

$passwordGenerationMethod = $this->processor->getProperty('passwordgenmethod','g');
$passwordGenerationMethod = $this->processor->getProperty('passwordgenmethod', 'g');
if ($passwordGenerationMethod !== 'user_email_specify' && ($newPassword !== null && $newPassword != 'false' || empty($id))) {
$passwordNotifyMethod = $this->processor->getProperty('passwordnotifymethod',null);
$passwordNotifyMethod = $this->processor->getProperty('passwordnotifymethod', null);
if (empty($passwordNotifyMethod)) {
$this->processor->addFieldError('password_notify_method',$this->modx->lexicon('user_err_not_specified_notification_method'));
$this->processor->addFieldError('password_notify_method', $this->modx->lexicon('user_err_not_specified_notification_method'));
}

if ($passwordGenerationMethod == 'g') {
$autoPassword = $this->user->generatePassword();
$this->user->set('password', $autoPassword);
$this->processor->newPassword= $autoPassword;
$this->processor->newPassword = $autoPassword;
} else {
$specifiedPassword = $this->processor->getProperty('specifiedpassword');
$confirmPassword = $this->processor->getProperty('confirmpassword');
if (empty($specifiedPassword)) {
$this->processor->addFieldError('specifiedpassword',$this->modx->lexicon('user_err_not_specified_password'));
$this->processor->addFieldError('specifiedpassword', $this->modx->lexicon('user_err_not_specified_password'));
} elseif ($specifiedPassword != $confirmPassword) {
$this->processor->addFieldError('confirmpassword',$this->modx->lexicon('user_err_password_no_match'));
$this->processor->addFieldError('confirmpassword', $this->modx->lexicon('user_err_password_no_match'));
} elseif (strlen($specifiedPassword) < $this->modx->getOption('password_min_length', null, 8, true)) {
$this->processor->addFieldError('specifiedpassword',$this->modx->lexicon('user_err_password_too_short'));
$this->processor->addFieldError('specifiedpassword', $this->modx->lexicon('user_err_password_too_short'));
} elseif (!preg_match('/^[^\'\x3c\x3e\(\);\x22\x7b\x7d\x2f\x5c]+$/', $specifiedPassword)) {
$this->processor->addFieldError('specifiedpassword', $this->modx->lexicon('user_err_password_invalid'));
} else {
$this->user->set('password',$specifiedPassword);
$this->user->set('password', $specifiedPassword);
$this->processor->newPassword = $specifiedPassword;
}
}
}
return $this->processor->newPassword;
}

public function checkEmail() {
public function checkEmail()
{
$email = $this->processor->getProperty('email');
if (empty($email)) {
$this->processor->addFieldError('email',$this->modx->lexicon('user_err_not_specified_email'));
$this->processor->addFieldError('email', $this->modx->lexicon('user_err_not_specified_email'));
}

if (!$this->modx->getOption('allow_multiple_emails',null,true)) {
if (!$this->modx->getOption('allow_multiple_emails', null, true)) {
/** @var modUserProfile $emailExists */
$emailExists = $this->modx->getObject(modUserProfile::class, ['email' => $email]);
if ($emailExists) {
if ($emailExists->get('internalKey') != $this->processor->getProperty('id')) {
$this->processor->addFieldError('email',$this->modx->lexicon('user_err_already_exists_email'));
$this->processor->addFieldError('email', $this->modx->lexicon('user_err_already_exists_email'));
}
}
}
return $email;
}

public function checkPhone() {
public function checkPhone()
{
$phone = $this->processor->getProperty('phone');
if (!empty($phone)) {
if ($this->modx->getOption('clean_phone_number',null,false)) {
$phone = str_replace(' ','',$phone);
$phone = str_replace('-','',$phone);
$phone = str_replace('(','',$phone);
$phone = str_replace(')','',$phone);
$phone = str_replace('+','',$phone);
$this->processor->setProperty('phone',$phone);
$this->profile->set('phone',$phone);
if ($this->modx->getOption('clean_phone_number', null, false)) {
$phone = str_replace(' ', '', $phone);
$phone = str_replace('-', '', $phone);
$phone = str_replace('(', '', $phone);
$phone = str_replace(')', '', $phone);
$phone = str_replace('+', '', $phone);
$this->processor->setProperty('phone', $phone);
$this->profile->set('phone', $phone);
}
}
}

public function checkCellPhone() {
public function checkCellPhone()
{
$phone = $this->processor->getProperty('mobilephone');
if (!empty($phone)) {
if ($this->modx->getOption('clean_phone_number',null,false)) {
$phone = str_replace(' ','',$phone);
$phone = str_replace('-','',$phone);
$phone = str_replace('(','',$phone);
$phone = str_replace(')','',$phone);
$phone = str_replace('+','',$phone);
$this->processor->setProperty('mobilephone',$phone);
$this->profile->set('mobilephone',$phone);
if ($this->modx->getOption('clean_phone_number', null, false)) {
$phone = str_replace(' ', '', $phone);
$phone = str_replace('-', '', $phone);
$phone = str_replace('(', '', $phone);
$phone = str_replace(')', '', $phone);
$phone = str_replace('+', '', $phone);
$this->processor->setProperty('mobilephone', $phone);
$this->profile->set('mobilephone', $phone);
}
}
}

public function checkBirthDate() {
public function checkBirthDate()
{
$birthDate = $this->processor->getProperty('dob');
if (!empty($birthDate)) {
$birthDate = strtotime($birthDate);
if (false === $birthDate) {
$this->processor->addFieldError('dob',$this->modx->lexicon('user_err_not_specified_dob'));
$date = \DateTimeImmutable::createFromFormat($this->modx->getOption('manager_date_format', null, 'Y-m-d', true), $birthDate);
if ($date === false) {
$this->processor->addFieldError('dob', $this->modx->lexicon('user_err_not_specified_dob'));
}
$this->processor->setProperty('dob',$birthDate);
$this->profile->set('dob',$birthDate);
$birthDate = $date->getTimestamp();
$this->processor->setProperty('dob', $birthDate);
$this->profile->set('dob', $birthDate);
}
}

public function checkBlocked() {
public function checkBlocked()
{
/* blocked until */
$blockedUntil = $this->processor->getProperty('blockeduntil');
if (!empty($blockedUntil)) {
$blockedUntil = str_replace('-','/',$blockedUntil);
$blockedUntil = str_replace('-', '/', $blockedUntil);
if (!$blockedUntil = strtotime($blockedUntil)) {
$this->processor->addFieldError('blockeduntil',$this->modx->lexicon('user_err_not_specified_blockeduntil'));
$this->processor->addFieldError('blockeduntil', $this->modx->lexicon('user_err_not_specified_blockeduntil'));
}
$this->processor->setProperty('blockeduntil',$blockedUntil);
$this->profile->set('blockeduntil',$blockedUntil);
$this->processor->setProperty('blockeduntil', $blockedUntil);
$this->profile->set('blockeduntil', $blockedUntil);
}

/* blocked after */
$blockedAfter = $this->processor->getProperty('blockedafter');
if (!empty($blockedAfter)) {
$blockedAfter = str_replace('-','/',$blockedAfter);
$blockedAfter = str_replace('-', '/', $blockedAfter);
if (!$blockedAfter = strtotime($blockedAfter)) {
$this->processor->addFieldError('blockedafter',$this->modx->lexicon('user_err_not_specified_blockedafter'));
$this->processor->addFieldError('blockedafter', $this->modx->lexicon('user_err_not_specified_blockedafter'));
}
$this->processor->setProperty('blockedafter',$blockedAfter);
$this->profile->set('blockedafter',$blockedAfter);
$this->processor->setProperty('blockedafter', $blockedAfter);
$this->profile->set('blockedafter', $blockedAfter);
}
}

}
Loading