diff --git a/system/typemill/Controllers/ControllerApiSystemUsers.php b/system/typemill/Controllers/ControllerApiSystemUsers.php index bc5d99d..a596aad 100644 --- a/system/typemill/Controllers/ControllerApiSystemUsers.php +++ b/system/typemill/Controllers/ControllerApiSystemUsers.php @@ -107,10 +107,19 @@ class ControllerApiSystemUsers extends Controller public function updateUser(Request $request, Response $response, $args) { - $params = $request->getParsedBody(); - $userdata = $params['userdata'] ?? false; - $username = $params['userdata']['username'] ?? false; - $isAdmin = $this->c->get('acl')->isAllowed($request->getAttribute('c_userrole'), 'user', 'write'); + $params = $request->getParsedBody(); + $userdata = $params['userdata'] ?? false; + $username = $params['userdata']['username'] ?? false; + $isAdmin = $this->c->get('acl')->isAllowed($request->getAttribute('c_userrole'), 'user', 'write'); + + if(!$userdata OR !$username) + { + $response->getBody()->write(json_encode([ + 'message' => Translations::translate('Userdata or username is missing.'), + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(400); + } $validate = new Validation(); @@ -128,11 +137,11 @@ class ControllerApiSystemUsers extends Controller } # if it is a non-admin-user - if(!$isAdmin) + if($isAdmin !== true) { # do not change userrole unset($userdata['userrole']); - + # if a non-admin-user tries to update another account if(($username !== $request->getAttribute('c_username'))) { @@ -144,50 +153,82 @@ class ControllerApiSystemUsers extends Controller } } - # cleanup password entry - if(isset($userdata['password']) AND $userdata['password'] == '') - { - unset($userdata['password']); - } - if(isset($userdata['newpassword']) AND $userdata['newpassword'] == '') - { - unset($userdata['newpassword']); - } + # make sure you set a user with password when you update, otherwise it will delete the password completely + $user = new User(); + $user->setUserWithPassword($username); - # validate passwort changes if valid input - if(isset($userdata['password']) OR isset($userdata['newpassword'])) - { - $validpass = $validate->newPassword($userdata); + # password validation + $pwerrors = []; + $oldpassword = ( isset($userdata['password']) AND ($userdata['password'] != '') ) ? $userdata['password'] : false; + $newpassword = ( isset($userdata['newpassword']) AND ($userdata['newpassword'] != '') ) ? $userdata['newpassword'] : false; + unset($userdata['password']); + unset($userdata['newpassword']); - if($validpass === true) + if($isAdmin === true) + { + # admins can change passwords without old password + if($newpassword) { - # encrypt new password - $userdata['password'] = $user->generatePassword($userdata['newpassword']); - } - elseif(is_array($validpass)) - { - foreach($validpass as $fieldname => $errors) + $validpass = $validate->newPasswordAdmin(['newpassword' => $newpassword]); + + if($validpass === true) { - $this->errors[$fieldname] = $errors[0]; + # encrypt new password + $userdata['password'] = $user->generatePassword($newpassword); + } + elseif(is_array($validpass)) + { + foreach($validpass as $fieldname => $errors) + { + $pwerrors[$fieldname] = $errors[0]; + } } } + } + else + { + # non-admins can change password only with new and old password + if($oldpassword OR $newpassword) + { + $validpass = $validate->newPassword(['password' => $oldpassword, 'newpassword' => $newpassword]); - # in all cases unset newpassword - unset($userdata['newpassword']); + if(is_array($validpass)) + { + foreach($validpass as $fieldname => $errors) + { + $pwerrors[$fieldname] = $errors[0]; + } + } + elseif(!password_verify($oldpassword, $user->getValue('password'))) + { + $pwerrors['password'] = 'Old password is wrong.'; + } + elseif($validpass === true) + { + # encrypt new password + $userdata['password'] = $user->generatePassword($newpassword); + } + } } - # make sure you set a user with password when you update, otherwise it will delete the password completely - $user = new User(); - $user->setUserWithPassword($username); + if(!empty($pwerrors)) + { + $response->getBody()->write(json_encode([ + 'message' => Translations::translate('Please correct your input.'), + 'errors' => $pwerrors + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(400); + } + + # we have to validate again because of additional dynamic fields $formdefinitions = $user->getUserFields($this->c->get('acl'), $request->getAttribute('c_userrole')); - - $validatedOutput = $validate->recursiveValidation($formdefinitions, $userdata); if(!empty($validate->errors)) { $response->getBody()->write(json_encode([ 'message' => Translations::translate('Please correct your input.'), - 'errors' => $validate->errors + 'errors' => $validateErrors ])); return $response->withHeader('Content-Type', 'application/json')->withStatus(400); diff --git a/system/typemill/Models/User.php b/system/typemill/Models/User.php index 0f22cd9..f011fba 100644 --- a/system/typemill/Models/User.php +++ b/system/typemill/Models/User.php @@ -54,6 +54,15 @@ class User return $this; } + public function getValue($key) + { + if(isset($this->user[$key])) + { + return $this->user[$key]; + } + return false; + } + public function setValue($key, $value) { $this->user[$key] = $value; diff --git a/system/typemill/Models/Validation.php b/system/typemill/Models/Validation.php index 04b4fe9..e51da6d 100644 --- a/system/typemill/Models/Validation.php +++ b/system/typemill/Models/Validation.php @@ -677,7 +677,20 @@ class Validation $v = new Validator($params); $v->rule('required', ['password', 'newpassword']); $v->rule('lengthBetween', 'newpassword', 5, 50); - $v->rule('equals', 'passwordrepeat', 'password'); + + if($v->validate()) + { + return true; + } + + return $v->errors(); + } + + public function newPasswordAdmin(array $params) + { + $v = new Validator($params); + $v->rule('required', ['newpassword']); + $v->rule('lengthBetween', 'newpassword', 5, 50); if($v->validate()) { diff --git a/system/typemill/Plugin.php b/system/typemill/Plugin.php index 8ed2578..78c5a85 100644 --- a/system/typemill/Plugin.php +++ b/system/typemill/Plugin.php @@ -89,7 +89,7 @@ abstract class Plugin implements EventSubscriberInterface return $data; } - protected function storePluginData($filename, $data, $method = NULL) + protected function storePluginData($filename, $data, $method = NULL, $pluginname = false) { $pluginname = $this->getPluginName($pluginname); diff --git a/system/typemill/Static/Plugins.php b/system/typemill/Static/Plugins.php index 13b8602..5b3c211 100644 --- a/system/typemill/Static/Plugins.php +++ b/system/typemill/Static/Plugins.php @@ -78,7 +78,9 @@ class Plugins public static function getPremiumLicense($className) { $premiumlist = [ - '\Plugins\html\html' => 'MAKER' + '\Plugins\html\html' => 'MAKER', + '\Plugins\html\register' => 'MAKER', + '\Plugins\html\seo' => 'MAKER' ]; if(isset($premiumList['className'])) diff --git a/system/typemill/settings/defaults.yaml b/system/typemill/settings/defaults.yaml index f6ec017..42d93c2 100644 --- a/system/typemill/settings/defaults.yaml +++ b/system/typemill/settings/defaults.yaml @@ -1,4 +1,4 @@ -version: '2.3.2' +version: '2.3.3' title: 'Typemill' author: 'Unknown' copyright: false