From e5f0e00742fb1a864e2d9dd5264ec47823294eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 5 Jan 2024 12:31:38 +0100 Subject: [PATCH] Apply password validation to all places --- app/controllers/api/account.php | 26 ++++++++++++++++++++------ app/controllers/api/users.php | 6 ++++-- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index c205a4beca..5e514880bb 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -119,7 +119,7 @@ App::post('/v1/account') } } - $hooks->trigger('passwordValidator', [$project, $password, &$user]); + $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, true]); $passwordHistory = $project->getAttribute('auths', [])['passwordHistory'] ?? 0; $password = Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS); @@ -196,7 +196,8 @@ App::post('/v1/account/sessions/email') ->inject('locale') ->inject('geodb') ->inject('queueForEvents') - ->action(function (string $email, string $password, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents) { + ->inject('hooks') + ->action(function (string $email, string $password, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents, Hooks $hooks) { $email = \strtolower($email); $protocol = $request->getProtocol(); @@ -215,6 +216,8 @@ App::post('/v1/account/sessions/email') $user->setAttributes($profile->getArrayCopy()); + $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, false]); + $duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; $detector = new Detector($request->getUserAgent('UNKNOWN')); @@ -1915,7 +1918,7 @@ App::patch('/v1/account/password') } } - $hooks->trigger('passwordValidator', [$project, $password, &$user]); + $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, true]); $user ->setAttribute('password', $newPassword) @@ -1954,7 +1957,9 @@ App::patch('/v1/account/email') ->inject('user') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $email, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { + ->inject('project') + ->inject('hooks') + ->action(function (string $email, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks) { // passwordUpdate will be empty if the user has never set a password $passwordUpdate = $user->getAttribute('passwordUpdate'); @@ -1965,6 +1970,8 @@ App::patch('/v1/account/email') throw new Exception(Exception::USER_INVALID_CREDENTIALS); } + $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, false]); + $email = \strtolower($email); // Makes sure this email is not already used in another identity @@ -2023,7 +2030,9 @@ App::patch('/v1/account/phone') ->inject('user') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $phone, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { + ->inject('project') + ->inject('hooks') + ->action(function (string $phone, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks) { // passwordUpdate will be empty if the user has never set a password $passwordUpdate = $user->getAttribute('passwordUpdate'); @@ -2034,6 +2043,8 @@ App::patch('/v1/account/phone') throw new Exception(Exception::USER_INVALID_CREDENTIALS); } + $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, false]); + $user ->setAttribute('phone', $phone) ->setAttribute('phoneVerification', false) // After this user needs to confirm phone number again @@ -2557,7 +2568,8 @@ App::put('/v1/account/recovery') ->inject('dbForProject') ->inject('project') ->inject('queueForEvents') - ->action(function (string $userId, string $secret, string $password, string $passwordAgain, Response $response, Document $user, Database $dbForProject, Document $project, Event $queueForEvents) { + ->inject('hooks') + ->action(function (string $userId, string $secret, string $password, string $passwordAgain, Response $response, Document $user, Database $dbForProject, Document $project, Event $queueForEvents, Hooks $hooks) { if ($password !== $passwordAgain) { throw new Exception(Exception::USER_PASSWORD_MISMATCH); } @@ -2591,6 +2603,8 @@ App::put('/v1/account/recovery') $history = array_slice($history, (count($history) - $historyLimit), $historyLimit); } + $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, true]); + $profile = $dbForProject->updateDocument('users', $profile->getId(), $profile ->setAttribute('password', $newPassword) ->setAttribute('passwordHistory', $history) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index d3679bdea0..35ca11bde9 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -99,7 +99,9 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e 'search' => implode(' ', [$userId, $email, $phone, $name]), ]); - $hooks->trigger('passwordValidator', [$project, $password, &$user]); + if($hash === 'plaintext') { + $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, true]); + } $password = (!empty($password)) ? ($hash === 'plaintext' ? Auth::passwordHash($password, $hash, $hashOptionsObject) : $password) : null; $user = $dbForProject->createDocument('users', $user); @@ -875,7 +877,7 @@ App::patch('/v1/users/:userId/password') } } - $hooks->trigger('passwordValidator', [$project, $password, &$user]); + $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, true]); $newPassword = Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS);