diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 64f13be9b..9245b7e6e 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -3,7 +3,15 @@ use PhpCsFixer\Config; use PhpCsFixer\Finder; -$finder = (new Finder())->in(__DIR__)->exclude(['vendor', 'node_modules', 'storage', 'bootstrap/cache']); +$finder = (new Finder()) + ->in(__DIR__) + ->exclude([ + 'vendor', + 'node_modules', + 'storage', + 'bootstrap/cache', + ]) + ->notName(['_ide_helper*']); return (new Config()) ->setRiskyAllowed(true) diff --git a/README.md b/README.md index 333a9b226..42e02d5c0 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ I would like to extend my sincere thanks to the following sponsors for helping f | [**ByteAnia**](https://byteania.com/?utm_source=pterodactyl) | ByteAnia offers the best performing and most affordable **Ryzen 5000 Series hosting** on the market for *unbeatable prices*! | | [**Aussie Server Hosts**](https://aussieserverhosts.com/) | No frills Australian Owned and operated High Performance Server hosting for some of the most demanding games serving Australia and New Zealand. | | [**VibeGAMES**](https://vibegames.net/) | VibeGAMES is a game server provider that specializes in DDOS protection for the games we offer. We have multiple locations in the US, Brazil, France, Germany, Singapore, Australia and South Africa.| +| [**RocketNode**](https://rocketnode.net) | RocketNode is a VPS and Game Server provider that offers the best performing VPS and Game hosting Solutions at affordable prices! | ## Documentation * [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html) diff --git a/app/Http/Controllers/Api/Client/AccountController.php b/app/Http/Controllers/Api/Client/AccountController.php index cbceb07c8..6c5a50e5c 100644 --- a/app/Http/Controllers/Api/Client/AccountController.php +++ b/app/Http/Controllers/Api/Client/AccountController.php @@ -55,12 +55,17 @@ class AccountController extends ClientApiController * Update the authenticated user's password. All existing sessions will be logged * out immediately. * - * @throws \Pterodactyl\Exceptions\Model\DataValidationException - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException + * @throws \Throwable */ public function updatePassword(UpdatePasswordRequest $request): Response { - $this->updateService->handle($request->user(), $request->validated()); + $user = $this->updateService->handle($request->user(), $request->validated()); + + // If you do not update the user in the session you'll end up working with a + // cached copy of the user that does not include the updated password. Do this + // to correctly store the new user details in the guard and allow the logout + // other devices functionality to work. + $this->sessionGuard->setUser($user); $this->authManager->logoutOtherDevices($request->input('password')); diff --git a/app/Http/Controllers/Api/Client/Servers/ResourceUtilizationController.php b/app/Http/Controllers/Api/Client/Servers/ResourceUtilizationController.php index 5bf8317eb..ba81d60d8 100644 --- a/app/Http/Controllers/Api/Client/Servers/ResourceUtilizationController.php +++ b/app/Http/Controllers/Api/Client/Servers/ResourceUtilizationController.php @@ -32,7 +32,6 @@ class ResourceUtilizationController extends ClientApiController * a flood of unnecessary API calls. * * @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException - * @throws \Illuminate\Contracts\Container\BindingResolutionException */ public function __invoke(GetServerRequest $request, Server $server): array { diff --git a/app/Http/Controllers/Api/Remote/Servers/ServerTransferController.php b/app/Http/Controllers/Api/Remote/Servers/ServerTransferController.php index e7dcb8805..6427c5cb8 100644 --- a/app/Http/Controllers/Api/Remote/Servers/ServerTransferController.php +++ b/app/Http/Controllers/Api/Remote/Servers/ServerTransferController.php @@ -123,12 +123,7 @@ class ServerTransferController extends Controller /** @var \Pterodactyl\Models\Server $server */ $server = $this->connection->transaction(function () use ($server, $transfer) { - $allocations = [$transfer->old_allocation]; - if (!empty($transfer->old_additional_allocations)) { - foreach ($transfer->old_additional_allocations as $allocation) { - $allocations[] = $allocation; - } - } + $allocations = array_merge([$transfer->old_allocation], $transfer->old_additional_allocations); // Remove the old allocations for the server and re-assign the server to the new // primary allocation and node. @@ -169,13 +164,7 @@ class ServerTransferController extends Controller $this->connection->transaction(function () use (&$transfer) { $transfer->forceFill(['successful' => false])->saveOrFail(); - $allocations = [$transfer->new_allocation]; - if (!empty($transfer->new_additional_allocations)) { - foreach ($transfer->new_additional_allocations as $allocation) { - $allocations[] = $allocation; - } - } - + $allocations = array_merge([$transfer->new_allocation], $transfer->new_additional_allocations); Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]); }); diff --git a/app/Http/Requests/Api/Client/Account/UpdateEmailRequest.php b/app/Http/Requests/Api/Client/Account/UpdateEmailRequest.php index 25f885ce3..6287ba585 100644 --- a/app/Http/Requests/Api/Client/Account/UpdateEmailRequest.php +++ b/app/Http/Requests/Api/Client/Account/UpdateEmailRequest.php @@ -3,18 +3,26 @@ namespace Pterodactyl\Http\Requests\Api\Client\Account; use Pterodactyl\Models\User; -use Pterodactyl\Http\Requests\Api\Client\AccountApiRequest; +use Illuminate\Container\Container; +use Illuminate\Contracts\Hashing\Hasher; +use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; use Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException; -class UpdateEmailRequest extends AccountApiRequest +class UpdateEmailRequest extends ClientApiRequest { /** * @throws \Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException */ public function authorize(): bool { + if (!parent::authorize()) { + return false; + } + + $hasher = Container::getInstance()->make(Hasher::class); + // Verify password matches when changing password or email. - if (!password_verify($this->input('password'), $this->user()->password)) { + if (!$hasher->check($this->input('password'), $this->user()->password)) { throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password')); } diff --git a/app/Http/Requests/Api/Client/Account/UpdatePasswordRequest.php b/app/Http/Requests/Api/Client/Account/UpdatePasswordRequest.php index 56d771338..de8215b07 100644 --- a/app/Http/Requests/Api/Client/Account/UpdatePasswordRequest.php +++ b/app/Http/Requests/Api/Client/Account/UpdatePasswordRequest.php @@ -2,18 +2,26 @@ namespace Pterodactyl\Http\Requests\Api\Client\Account; -use Pterodactyl\Http\Requests\Api\Client\AccountApiRequest; +use Illuminate\Container\Container; +use Illuminate\Contracts\Hashing\Hasher; +use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest; use Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException; -class UpdatePasswordRequest extends AccountApiRequest +class UpdatePasswordRequest extends ClientApiRequest { /** * @throws \Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException */ public function authorize(): bool { + if (!parent::authorize()) { + return false; + } + + $hasher = Container::getInstance()->make(Hasher::class); + // Verify password matches when changing password or email. - if (!password_verify($this->input('current_password'), $this->user()->password)) { + if (!$hasher->check($this->input('current_password'), $this->user()->password)) { throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password')); } diff --git a/app/Services/Backups/InitiateBackupService.php b/app/Services/Backups/InitiateBackupService.php index 634f17cfe..d368fb609 100644 --- a/app/Services/Backups/InitiateBackupService.php +++ b/app/Services/Backups/InitiateBackupService.php @@ -9,7 +9,6 @@ use Pterodactyl\Models\Backup; use Pterodactyl\Models\Server; use Illuminate\Database\ConnectionInterface; use Pterodactyl\Extensions\Backups\BackupManager; -use Illuminate\Database\Eloquent\Relations\HasMany; use Pterodactyl\Repositories\Eloquent\BackupRepository; use Pterodactyl\Repositories\Wings\DaemonBackupRepository; use Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException; diff --git a/app/Services/Users/UserUpdateService.php b/app/Services/Users/UserUpdateService.php index 0c7e1c172..31f4010b6 100644 --- a/app/Services/Users/UserUpdateService.php +++ b/app/Services/Users/UserUpdateService.php @@ -5,7 +5,6 @@ namespace Pterodactyl\Services\Users; use Pterodactyl\Models\User; use Illuminate\Contracts\Hashing\Hasher; use Pterodactyl\Traits\Services\HasUserLevels; -use Pterodactyl\Repositories\Eloquent\UserRepository; class UserUpdateService { @@ -16,29 +15,20 @@ class UserUpdateService */ private $hasher; - /** - * @var \Pterodactyl\Repositories\Eloquent\UserRepository - */ - private $repository; - /** * UpdateService constructor. */ - public function __construct(Hasher $hasher, UserRepository $repository) + public function __construct(Hasher $hasher) { $this->hasher = $hasher; - $this->repository = $repository; } /** - * Update the user model instance. + * Update the user model instance and return the updated model. * - * @return \Pterodactyl\Models\User - * - * @throws \Pterodactyl\Exceptions\Model\DataValidationException - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException + * @throws \Throwable */ - public function handle(User $user, array $data) + public function handle(User $user, array $data): User { if (!empty(array_get($data, 'password'))) { $data['password'] = $this->hasher->make($data['password']); @@ -46,9 +36,8 @@ class UserUpdateService unset($data['password']); } - /** @var \Pterodactyl\Models\User $response */ - $response = $this->repository->update($user->id, $data); + $user->forceFill($data)->saveOrFail(); - return $response; + return $user->refresh(); } } diff --git a/config/pterodactyl.php b/config/pterodactyl.php index db08688d3..b7cd12559 100644 --- a/config/pterodactyl.php +++ b/config/pterodactyl.php @@ -141,7 +141,7 @@ return [ 'schedules' => [ // The total number of tasks that can exist for any given schedule at once. - 'per_schedule_task_limit' => 10, + 'per_schedule_task_limit' => env('PTERODACTYL_PER_SCHEDULE_TASK_LIMIT', 10), ], 'allocations' => [ diff --git a/resources/scripts/components/dashboard/forms/SetupTwoFactorModal.tsx b/resources/scripts/components/dashboard/forms/SetupTwoFactorModal.tsx index 4bb73f368..aea603995 100644 --- a/resources/scripts/components/dashboard/forms/SetupTwoFactorModal.tsx +++ b/resources/scripts/components/dashboard/forms/SetupTwoFactorModal.tsx @@ -80,8 +80,8 @@ const SetupTwoFactorModal = () => { <>
- Two-factor authentication has been enabled on your account. Should you loose access to - this device you'll need to use one of the codes displayed below in order to access your + Two-factor authentication has been enabled on your account. Should you lose access to + your authenticator device, you'll need to use one of the codes displayed below in order to access your account.
diff --git a/tests/Integration/Api/Client/AccountControllerTest.php b/tests/Integration/Api/Client/AccountControllerTest.php index 255a413f1..10f18e86b 100644 --- a/tests/Integration/Api/Client/AccountControllerTest.php +++ b/tests/Integration/Api/Client/AccountControllerTest.php @@ -2,10 +2,9 @@ namespace Pterodactyl\Tests\Integration\Api\Client; -use Mockery; use Pterodactyl\Models\User; use Illuminate\Http\Response; -use Illuminate\Auth\AuthManager; +use Illuminate\Support\Facades\Hash; class AccountControllerTest extends ClientApiIntegrationTestCase { @@ -104,10 +103,7 @@ class AccountControllerTest extends ClientApiIntegrationTestCase /** @var \Pterodactyl\Models\User $user */ $user = User::factory()->create(); - $mock = Mockery::mock(AuthManager::class); - $mock->expects('logoutOtherDevices')->with('New_Password1'); - - $this->app->instance(AuthManager::class, $mock); + $initialHash = $user->password; $response = $this->actingAs($user)->putJson('/api/client/account/password', [ 'current_password' => 'password', @@ -115,6 +111,12 @@ class AccountControllerTest extends ClientApiIntegrationTestCase 'password_confirmation' => 'New_Password1', ]); + $user = $user->refresh(); + + $this->assertNotEquals($user->password, $initialHash); + $this->assertTrue(Hash::check('New_Password1', $user->password)); + $this->assertFalse(Hash::check('password', $user->password)); + $response->assertStatus(Response::HTTP_NO_CONTENT); }