Merge branch 'develop' into v2
This commit is contained in:
commit
b26556e201
12 changed files with 59 additions and 51 deletions
|
@ -3,7 +3,15 @@
|
||||||
use PhpCsFixer\Config;
|
use PhpCsFixer\Config;
|
||||||
use PhpCsFixer\Finder;
|
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())
|
return (new Config())
|
||||||
->setRiskyAllowed(true)
|
->setRiskyAllowed(true)
|
||||||
|
|
|
@ -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*! |
|
| [**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. |
|
| [**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.|
|
| [**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
|
## Documentation
|
||||||
* [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html)
|
* [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html)
|
||||||
|
|
|
@ -55,12 +55,17 @@ class AccountController extends ClientApiController
|
||||||
* Update the authenticated user's password. All existing sessions will be logged
|
* Update the authenticated user's password. All existing sessions will be logged
|
||||||
* out immediately.
|
* out immediately.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Throwable
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function updatePassword(UpdatePasswordRequest $request): Response
|
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'));
|
$this->authManager->logoutOtherDevices($request->input('password'));
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ class ResourceUtilizationController extends ClientApiController
|
||||||
* a flood of unnecessary API calls.
|
* a flood of unnecessary API calls.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
|
||||||
*/
|
*/
|
||||||
public function __invoke(GetServerRequest $request, Server $server): array
|
public function __invoke(GetServerRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,12 +123,7 @@ class ServerTransferController extends Controller
|
||||||
|
|
||||||
/** @var \Pterodactyl\Models\Server $server */
|
/** @var \Pterodactyl\Models\Server $server */
|
||||||
$server = $this->connection->transaction(function () use ($server, $transfer) {
|
$server = $this->connection->transaction(function () use ($server, $transfer) {
|
||||||
$allocations = [$transfer->old_allocation];
|
$allocations = array_merge([$transfer->old_allocation], $transfer->old_additional_allocations);
|
||||||
if (!empty($transfer->old_additional_allocations)) {
|
|
||||||
foreach ($transfer->old_additional_allocations as $allocation) {
|
|
||||||
$allocations[] = $allocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the old allocations for the server and re-assign the server to the new
|
// Remove the old allocations for the server and re-assign the server to the new
|
||||||
// primary allocation and node.
|
// primary allocation and node.
|
||||||
|
@ -169,13 +164,7 @@ class ServerTransferController extends Controller
|
||||||
$this->connection->transaction(function () use (&$transfer) {
|
$this->connection->transaction(function () use (&$transfer) {
|
||||||
$transfer->forceFill(['successful' => false])->saveOrFail();
|
$transfer->forceFill(['successful' => false])->saveOrFail();
|
||||||
|
|
||||||
$allocations = [$transfer->new_allocation];
|
$allocations = array_merge([$transfer->new_allocation], $transfer->new_additional_allocations);
|
||||||
if (!empty($transfer->new_additional_allocations)) {
|
|
||||||
foreach ($transfer->new_additional_allocations as $allocation) {
|
|
||||||
$allocations[] = $allocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]);
|
Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,18 +3,26 @@
|
||||||
namespace Pterodactyl\Http\Requests\Api\Client\Account;
|
namespace Pterodactyl\Http\Requests\Api\Client\Account;
|
||||||
|
|
||||||
use Pterodactyl\Models\User;
|
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;
|
use Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException;
|
||||||
|
|
||||||
class UpdateEmailRequest extends AccountApiRequest
|
class UpdateEmailRequest extends ClientApiRequest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @throws \Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException
|
* @throws \Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException
|
||||||
*/
|
*/
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
|
if (!parent::authorize()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hasher = Container::getInstance()->make(Hasher::class);
|
||||||
|
|
||||||
// Verify password matches when changing password or email.
|
// 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'));
|
throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,26 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Requests\Api\Client\Account;
|
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;
|
use Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException;
|
||||||
|
|
||||||
class UpdatePasswordRequest extends AccountApiRequest
|
class UpdatePasswordRequest extends ClientApiRequest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @throws \Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException
|
* @throws \Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException
|
||||||
*/
|
*/
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
|
if (!parent::authorize()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hasher = Container::getInstance()->make(Hasher::class);
|
||||||
|
|
||||||
// Verify password matches when changing password or email.
|
// 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'));
|
throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ use Pterodactyl\Models\Backup;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use Pterodactyl\Extensions\Backups\BackupManager;
|
use Pterodactyl\Extensions\Backups\BackupManager;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Pterodactyl\Repositories\Eloquent\BackupRepository;
|
use Pterodactyl\Repositories\Eloquent\BackupRepository;
|
||||||
use Pterodactyl\Repositories\Wings\DaemonBackupRepository;
|
use Pterodactyl\Repositories\Wings\DaemonBackupRepository;
|
||||||
use Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException;
|
use Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException;
|
||||||
|
|
|
@ -5,7 +5,6 @@ namespace Pterodactyl\Services\Users;
|
||||||
use Pterodactyl\Models\User;
|
use Pterodactyl\Models\User;
|
||||||
use Illuminate\Contracts\Hashing\Hasher;
|
use Illuminate\Contracts\Hashing\Hasher;
|
||||||
use Pterodactyl\Traits\Services\HasUserLevels;
|
use Pterodactyl\Traits\Services\HasUserLevels;
|
||||||
use Pterodactyl\Repositories\Eloquent\UserRepository;
|
|
||||||
|
|
||||||
class UserUpdateService
|
class UserUpdateService
|
||||||
{
|
{
|
||||||
|
@ -16,29 +15,20 @@ class UserUpdateService
|
||||||
*/
|
*/
|
||||||
private $hasher;
|
private $hasher;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\UserRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateService constructor.
|
* UpdateService constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(Hasher $hasher, UserRepository $repository)
|
public function __construct(Hasher $hasher)
|
||||||
{
|
{
|
||||||
$this->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 \Throwable
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function handle(User $user, array $data)
|
public function handle(User $user, array $data): User
|
||||||
{
|
{
|
||||||
if (!empty(array_get($data, 'password'))) {
|
if (!empty(array_get($data, 'password'))) {
|
||||||
$data['password'] = $this->hasher->make($data['password']);
|
$data['password'] = $this->hasher->make($data['password']);
|
||||||
|
@ -46,9 +36,8 @@ class UserUpdateService
|
||||||
unset($data['password']);
|
unset($data['password']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var \Pterodactyl\Models\User $response */
|
$user->forceFill($data)->saveOrFail();
|
||||||
$response = $this->repository->update($user->id, $data);
|
|
||||||
|
|
||||||
return $response;
|
return $user->refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ return [
|
||||||
|
|
||||||
'schedules' => [
|
'schedules' => [
|
||||||
// The total number of tasks that can exist for any given schedule at once.
|
// 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' => [
|
'allocations' => [
|
||||||
|
|
|
@ -80,8 +80,8 @@ const SetupTwoFactorModal = () => {
|
||||||
<>
|
<>
|
||||||
<h2 css={tw`text-2xl mb-4`}>Two-factor authentication enabled</h2>
|
<h2 css={tw`text-2xl mb-4`}>Two-factor authentication enabled</h2>
|
||||||
<p css={tw`text-neutral-300`}>
|
<p css={tw`text-neutral-300`}>
|
||||||
Two-factor authentication has been enabled on your account. Should you loose access to
|
Two-factor authentication has been enabled on your account. Should you lose access to
|
||||||
this device you'll need to use one of the codes displayed below in order to access your
|
your authenticator device, you'll need to use one of the codes displayed below in order to access your
|
||||||
account.
|
account.
|
||||||
</p>
|
</p>
|
||||||
<p css={tw`text-neutral-300 mt-4`}>
|
<p css={tw`text-neutral-300 mt-4`}>
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Tests\Integration\Api\Client;
|
namespace Pterodactyl\Tests\Integration\Api\Client;
|
||||||
|
|
||||||
use Mockery;
|
|
||||||
use Pterodactyl\Models\User;
|
use Pterodactyl\Models\User;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Auth\AuthManager;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
class AccountControllerTest extends ClientApiIntegrationTestCase
|
class AccountControllerTest extends ClientApiIntegrationTestCase
|
||||||
{
|
{
|
||||||
|
@ -104,10 +103,7 @@ class AccountControllerTest extends ClientApiIntegrationTestCase
|
||||||
/** @var \Pterodactyl\Models\User $user */
|
/** @var \Pterodactyl\Models\User $user */
|
||||||
$user = User::factory()->create();
|
$user = User::factory()->create();
|
||||||
|
|
||||||
$mock = Mockery::mock(AuthManager::class);
|
$initialHash = $user->password;
|
||||||
$mock->expects('logoutOtherDevices')->with('New_Password1');
|
|
||||||
|
|
||||||
$this->app->instance(AuthManager::class, $mock);
|
|
||||||
|
|
||||||
$response = $this->actingAs($user)->putJson('/api/client/account/password', [
|
$response = $this->actingAs($user)->putJson('/api/client/account/password', [
|
||||||
'current_password' => 'password',
|
'current_password' => 'password',
|
||||||
|
@ -115,6 +111,12 @@ class AccountControllerTest extends ClientApiIntegrationTestCase
|
||||||
'password_confirmation' => 'New_Password1',
|
'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);
|
$response->assertStatus(Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue