diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e397ace2..c8459c46f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines. ### Changed * Attempting to upload a folder via the web file manager will now display a warning telling the user to use SFTP. +* Changing your account password will now log out all other sessions that currently exist for that user. ## v0.7.7 (Derelict Dermodactylus) ### Fixed diff --git a/app/Http/Controllers/Base/AccountController.php b/app/Http/Controllers/Base/AccountController.php index b6a433bb4..90d590ff2 100644 --- a/app/Http/Controllers/Base/AccountController.php +++ b/app/Http/Controllers/Base/AccountController.php @@ -3,7 +3,9 @@ namespace Pterodactyl\Http\Controllers\Base; use Pterodactyl\Models\User; +use Illuminate\Auth\AuthManager; use Prologue\Alerts\AlertsMessageBag; +use Illuminate\Contracts\Session\Session; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Services\Users\UserUpdateService; use Pterodactyl\Http\Requests\Base\AccountDataFormRequest; @@ -15,6 +17,11 @@ class AccountController extends Controller */ protected $alert; + /** + * @var \Illuminate\Auth\SessionGuard + */ + protected $sessionGuard; + /** * @var \Pterodactyl\Services\Users\UserUpdateService */ @@ -24,12 +31,14 @@ class AccountController extends Controller * AccountController constructor. * * @param \Prologue\Alerts\AlertsMessageBag $alert + * @param \Illuminate\Auth\AuthManager $authManager * @param \Pterodactyl\Services\Users\UserUpdateService $updateService */ - public function __construct(AlertsMessageBag $alert, UserUpdateService $updateService) + public function __construct(AlertsMessageBag $alert, AuthManager $authManager, UserUpdateService $updateService) { $this->alert = $alert; $this->updateService = $updateService; + $this->sessionGuard = $authManager->guard(); } /** @@ -50,21 +59,26 @@ class AccountController extends Controller * * @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException - * @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException */ public function update(AccountDataFormRequest $request) { - $data = []; + // Prevent logging this specific session out when the password is changed. This will + // automatically update the user's password anyways, so no need to do anything else here. if ($request->input('do_action') === 'password') { - $data['password'] = $request->input('new_password'); - } elseif ($request->input('do_action') === 'email') { - $data['email'] = $request->input('new_email'); - } elseif ($request->input('do_action') === 'identity') { - $data = $request->only(['name_first', 'name_last', 'username']); + $this->sessionGuard->logoutOtherDevices($request->input('new_password')); + } else { + if ($request->input('do_action') === 'email') { + $data = ['email' => $request->input('new_email')]; + } elseif ($request->input('do_action') === 'identity') { + $data = $request->only(['name_first', 'name_last', 'username']); + } else { + $data = []; + } + + $this->updateService->setUserLevel(User::USER_LEVEL_USER); + $this->updateService->handle($request->user(), $data); } - $this->updateService->setUserLevel(User::USER_LEVEL_USER); - $this->updateService->handle($request->user(), $data); $this->alert->success(trans('base.account.details_updated'))->flash(); return redirect()->route('account'); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 404c40ae9..5a5b9d2b4 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -19,6 +19,7 @@ use Pterodactyl\Http\Middleware\Api\AuthenticateKey; use Illuminate\Routing\Middleware\SubstituteBindings; use Pterodactyl\Http\Middleware\AccessingValidServer; use Pterodactyl\Http\Middleware\Api\SetSessionDriver; +use Illuminate\Session\Middleware\AuthenticateSession; use Illuminate\View\Middleware\ShareErrorsFromSession; use Pterodactyl\Http\Middleware\MaintenanceMiddleware; use Pterodactyl\Http\Middleware\RedirectIfAuthenticated; @@ -64,6 +65,7 @@ class Kernel extends HttpKernel EncryptCookies::class, AddQueuedCookiesToResponse::class, StartSession::class, + AuthenticateSession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, SubstituteBindings::class, diff --git a/tests/Unit/Http/Controllers/Base/AccountControllerTest.php b/tests/Unit/Http/Controllers/Base/AccountControllerTest.php index 968019ad7..2b3fc674a 100644 --- a/tests/Unit/Http/Controllers/Base/AccountControllerTest.php +++ b/tests/Unit/Http/Controllers/Base/AccountControllerTest.php @@ -4,6 +4,8 @@ namespace Tests\Unit\Http\Controllers\Base; use Mockery as m; use Pterodactyl\Models\User; +use Illuminate\Auth\AuthManager; +use Illuminate\Auth\SessionGuard; use Prologue\Alerts\AlertsMessageBag; use Pterodactyl\Services\Users\UserUpdateService; use Tests\Unit\Http\Controllers\ControllerTestCase; @@ -17,6 +19,16 @@ class AccountControllerTest extends ControllerTestCase */ protected $alert; + /** + * @var \Illuminate\Auth\AuthManager|\Mockery\Mock + */ + protected $authManager; + + /** + * @var \Illuminate\Auth\SessionGuard|\Mockery\Mock + */ + protected $sessionGuard; + /** * @var \Pterodactyl\Services\Users\UserUpdateService|\Mockery\Mock */ @@ -31,6 +43,10 @@ class AccountControllerTest extends ControllerTestCase $this->alert = m::mock(AlertsMessageBag::class); $this->updateService = m::mock(UserUpdateService::class); + $this->authManager = m::mock(AuthManager::class); + $this->sessionGuard = m::mock(SessionGuard::class); + + $this->authManager->shouldReceive('guard')->once()->andReturn($this->sessionGuard); } /** @@ -50,13 +66,11 @@ class AccountControllerTest extends ControllerTestCase public function testUpdateControllerForPassword() { $this->setRequestMockClass(AccountDataFormRequest::class); - $user = $this->generateRequestUserModel(); $this->request->shouldReceive('input')->with('do_action')->andReturn('password'); $this->request->shouldReceive('input')->with('new_password')->once()->andReturn('test-password'); + $this->sessionGuard->shouldReceive('logoutOtherDevices')->once()->with('test-password')->andReturnSelf(); - $this->updateService->shouldReceive('setUserLevel')->with(User::USER_LEVEL_USER)->once()->andReturnNull(); - $this->updateService->shouldReceive('handle')->with($user, ['password' => 'test-password'])->once()->andReturn(collect()); $this->alert->shouldReceive('success->flash')->once()->andReturnNull(); $response = $this->getController()->update($this->request); @@ -113,6 +127,6 @@ class AccountControllerTest extends ControllerTestCase */ private function getController(): AccountController { - return new AccountController($this->alert, $this->updateService); + return new AccountController($this->alert, $this->authManager, $this->updateService); } }