diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index aecb4e7f8..24201f304 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1585,16 +1585,15 @@ App::patch('/v1/account/password') $newPassword = Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS); $historyLimit = $project->getAttribute('auths', [])['passwordHistory'] ?? 0; - $history = []; + $history = $user->getAttribute('passwordHistory', []); if ($historyLimit > 0) { - $history = $user->getAttribute('passwordHistory', []); $validator = new PasswordHistory($history, $user->getAttribute('hash'), $user->getAttribute('hashOptions')); if (!$validator->isValid($password)) { throw new Exception(Exception::USER_PASSWORD_RECENTLY_USED); } $history[] = $newPassword; - array_slice($history, (count($history) - $historyLimit), $historyLimit); + $history = array_slice($history, (count($history) - $historyLimit), $historyLimit); } if ($project->getAttribute('auths', [])['disallowPersonalData'] ?? false) { @@ -2199,8 +2198,9 @@ App::put('/v1/account/recovery') ->param('passwordAgain', '', new Password(), 'Repeat new user password. Must be at least 8 chars.') ->inject('response') ->inject('dbForProject') + ->inject('project') ->inject('events') - ->action(function (string $userId, string $secret, string $password, string $passwordAgain, Response $response, Database $dbForProject, Event $events) { + ->action(function (string $userId, string $secret, string $password, string $passwordAgain, Response $response, Database $dbForProject, Document $project, Event $events) { if ($password !== $passwordAgain) { throw new Exception(Exception::USER_PASSWORD_MISMATCH); } @@ -2220,8 +2220,23 @@ App::put('/v1/account/recovery') Authorization::setRole(Role::user($profile->getId())->toString()); + $newPassword = Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS); + + $historyLimit = $project->getAttribute('auths', [])['passwordHistory'] ?? 0; + $history = $profile->getAttribute('passwordHistory', []); + if ($historyLimit > 0) { + $validator = new PasswordHistory($history, $profile->getAttribute('hash'), $profile->getAttribute('hashOptions')); + if (!$validator->isValid($password)) { + throw new Exception(Exception::USER_PASSWORD_RECENTLY_USED); + } + + $history[] = $newPassword; + $history = array_slice($history, (count($history) - $historyLimit), $historyLimit); + } + $profile = $dbForProject->updateDocument('users', $profile->getId(), $profile - ->setAttribute('password', Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS)) + ->setAttribute('password', $newPassword) + ->setAttribute('passwordHistory', $history) ->setAttribute('passwordUpdate', DateTime::now()) ->setAttribute('hash', Auth::DEFAULT_ALGO) ->setAttribute('hashOptions', Auth::DEFAULT_ALGO_OPTIONS) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 33285d2c7..7f7486731 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -824,16 +824,15 @@ App::patch('/v1/users/:userId/password') $newPassword = Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS); $historyLimit = $project->getAttribute('auths', [])['passwordHistory'] ?? 0; - $history = []; + $history = $user->getAttribute('passwordHistory', []); if ($historyLimit > 0) { - $history = $user->getAttribute('passwordHistory', []); $validator = new PasswordHistory($history, $user->getAttribute('hash'), $user->getAttribute('hashOptions')); if (!$validator->isValid($password)) { throw new Exception(Exception::USER_PASSWORD_RECENTLY_USED); } $history[] = $newPassword; - array_slice($history, (count($history) - $historyLimit), $historyLimit); + $history = array_slice($history, (count($history) - $historyLimit), $historyLimit); } $user diff --git a/composer.lock b/composer.lock index 9796216c0..fd1bf47bb 100644 --- a/composer.lock +++ b/composer.lock @@ -2962,16 +2962,16 @@ }, { "name": "webonyx/graphql-php", - "version": "v14.11.9", + "version": "v14.11.10", "source": { "type": "git", "url": "https://github.com/webonyx/graphql-php.git", - "reference": "ff91c9f3cf241db702e30b2c42bcc0920e70ac70" + "reference": "d9c2fdebc6aa01d831bc2969da00e8588cffef19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/ff91c9f3cf241db702e30b2c42bcc0920e70ac70", - "reference": "ff91c9f3cf241db702e30b2c42bcc0920e70ac70", + "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/d9c2fdebc6aa01d831bc2969da00e8588cffef19", + "reference": "d9c2fdebc6aa01d831bc2969da00e8588cffef19", "shasum": "" }, "require": { @@ -2991,8 +2991,7 @@ "phpunit/phpunit": "^7.2 || ^8.5", "psr/http-message": "^1.0", "react/promise": "2.*", - "simpod/php-coveralls-mirror": "^3.0", - "squizlabs/php_codesniffer": "3.5.4" + "simpod/php-coveralls-mirror": "^3.0" }, "suggest": { "psr/http-message": "To use standard GraphQL server", @@ -3016,7 +3015,7 @@ ], "support": { "issues": "https://github.com/webonyx/graphql-php/issues", - "source": "https://github.com/webonyx/graphql-php/tree/v14.11.9" + "source": "https://github.com/webonyx/graphql-php/tree/v14.11.10" }, "funding": [ { @@ -3024,22 +3023,22 @@ "type": "open_collective" } ], - "time": "2023-01-06T12:12:50+00:00" + "time": "2023-07-05T14:23:37+00:00" } ], "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.33.1", + "version": "0.33.7", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "551cdae31a68b19874f10ca321b1d08cfa06a13f" + "reference": "9f5db4a637b23879ceacea9ed2d33b0486771ffc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/551cdae31a68b19874f10ca321b1d08cfa06a13f", - "reference": "551cdae31a68b19874f10ca321b1d08cfa06a13f", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/9f5db4a637b23879ceacea9ed2d33b0486771ffc", + "reference": "9f5db4a637b23879ceacea9ed2d33b0486771ffc", "shasum": "" }, "require": { @@ -3075,9 +3074,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.33.1" + "source": "https://github.com/appwrite/sdk-generator/tree/0.33.7" }, - "time": "2023-05-16T04:37:34+00:00" + "time": "2023-07-12T12:15:43+00:00" }, { "name": "doctrine/deprecations", @@ -3381,16 +3380,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.5", + "version": "v4.16.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e" + "reference": "19526a33fb561ef417e822e85f08a00db4059c17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e", - "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/19526a33fb561ef417e822e85f08a00db4059c17", + "reference": "19526a33fb561ef417e822e85f08a00db4059c17", "shasum": "" }, "require": { @@ -3431,9 +3430,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.5" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.16.0" }, - "time": "2023-05-19T20:20:00+00:00" + "time": "2023-06-25T14:52:30+00:00" }, { "name": "phar-io/manifest", @@ -3784,16 +3783,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.22.0", + "version": "1.22.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "ec58baf7b3c7f1c81b3b00617c953249fb8cf30c" + "reference": "65c39594fbd8c67abfc68bb323f86447bab79cc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/ec58baf7b3c7f1c81b3b00617c953249fb8cf30c", - "reference": "ec58baf7b3c7f1c81b3b00617c953249fb8cf30c", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/65c39594fbd8c67abfc68bb323f86447bab79cc0", + "reference": "65c39594fbd8c67abfc68bb323f86447bab79cc0", "shasum": "" }, "require": { @@ -3825,9 +3824,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.22.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.22.1" }, - "time": "2023-06-01T12:35:21+00:00" + "time": "2023-06-29T20:46:06+00:00" }, { "name": "phpunit/php-code-coverage", @@ -5675,5 +5674,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } diff --git a/phpunit.xml b/phpunit.xml index f83f9f0fa..3d15bbd21 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,7 +6,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" + stopOnFailure="true" >