diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index bd44fecd0..65cef226d 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -1,4 +1,4 @@ -name: Publish Docker Image +name: Docker on: push: @@ -8,16 +8,16 @@ on: jobs: push: - name: Push Image to GitHub Packages + name: Push runs-on: ubuntu-20.04 # Always run against a tag, even if the commit into the tag has [docker skip] # within the commit message. if: "!contains(github.ref, 'develop') || (!contains(github.event.head_commit.message, 'skip docker') && !contains(github.event.head_commit.message, 'docker skip'))" steps: - - name: Code Checkout + - name: Code checkout uses: actions/checkout@v3 - - name: Docker Metadata + - name: Docker metadata uses: docker/metadata-action@v4 id: docker_meta with: @@ -26,10 +26,10 @@ jobs: - name: Setup QEMU uses: docker/setup-qemu-action@v2 - - name: Setup Docker Buildx + - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 - - name: Docker Login + - name: Docker login uses: docker/login-action@v2 with: registry: ghcr.io diff --git a/.github/workflows/ci.yaml b/.github/workflows/laravel.yaml similarity index 70% rename from .github/workflows/ci.yaml rename to .github/workflows/laravel.yaml index 28ce63e4a..56a597b48 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/laravel.yaml @@ -1,4 +1,4 @@ -name: Tests +name: Laravel on: push: @@ -11,8 +11,58 @@ on: - "1.0-develop" jobs: + analysis: + name: Static Analysis + runs-on: ubuntu-20.04 + env: + APP_ENV: testing + APP_DEBUG: "true" + APP_KEY: SomeRandomString3232RandomString + CACHE_DRIVER: array + MAIL_MAILER: array + SESSION_DRIVER: array + QUEUE_CONNECTION: sync + steps: + - name: Code checkout + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip + tools: composer:v2 + coverage: none + + - name: Install dependencies + run: composer install --no-interaction --no-progress --no-suggest --prefer-dist + + - name: Analyze + run: vendor/bin/phpstan analyse + + lint: + name: Lint + runs-on: ubuntu-20.04 + steps: + - name: Code checkout + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + extensions: bcmath, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip + tools: composer:v2 + coverage: none + + - name: Install dependencies + run: composer install --no-interaction --no-progress --no-suggest --prefer-dist + + - name: PHP CS Fixer + run: vendor/bin/php-cs-fixer fix --dry-run --diff + mysql: - name: MySQL + name: Tests (MySQL) runs-on: ubuntu-20.04 strategy: fail-fast: false @@ -36,20 +86,17 @@ jobs: APP_TIMEZONE: UTC APP_URL: http://localhost/ APP_ENVIRONMENT_ONLY: "true" - - DB_CONNECTION: mysql - DB_HOST: 127.0.0.1 - DB_DATABASE: testing - DB_USERNAME: root - CACHE_DRIVER: array MAIL_MAILER: array SESSION_DRIVER: array QUEUE_CONNECTION: sync - HASHIDS_SALT: test123 + DB_CONNECTION: mysql + DB_HOST: 127.0.0.1 + DB_DATABASE: testing + DB_USERNAME: root steps: - - name: Code Checkout + - name: Code checkout uses: actions/checkout@v3 - name: Get cache directory @@ -78,7 +125,6 @@ jobs: - name: Unit tests run: vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Unit - if: ${{ always() }} env: DB_HOST: UNIT_NO_DB @@ -88,7 +134,7 @@ jobs: DB_PORT: ${{ job.services.database.ports[3306] }} postgres: - name: PostgreSQL + name: Tests (PostgreSQL) runs-on: ubuntu-20.04 if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, 'ci skip')" strategy: @@ -114,35 +160,32 @@ jobs: APP_TIMEZONE: UTC APP_URL: http://localhost/ APP_ENVIRONMENT_ONLY: "true" - + CACHE_DRIVER: array + MAIL_MAILER: array + SESSION_DRIVER: array + QUEUE_CONNECTION: sync + HASHIDS_SALT: test123 DB_CONNECTION: pgsql DB_HOST: 127.0.0.1 DB_DATABASE: testing DB_USERNAME: postgres DB_PASSWORD: postgres - - CACHE_DRIVER: array - MAIL_MAILER: array - SESSION_DRIVER: array - QUEUE_CONNECTION: sync - - HASHIDS_SALT: test123 steps: - - name: Code Checkout + - name: Code checkout uses: actions/checkout@v3 - name: Get cache directory id: composer-cache run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache uses: actions/cache@v3 with: - path: | - ~/.php_cs.cache - ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-cache-${{ matrix.php }}-${{ hashFiles('**.composer.lock') }} + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-${{ matrix.php }}- - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -157,7 +200,6 @@ jobs: - name: Unit tests run: vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Unit - if: ${{ always() }} env: DB_HOST: UNIT_NO_DB diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml deleted file mode 100644 index a48c6b14e..000000000 --- a/.github/workflows/lint.yaml +++ /dev/null @@ -1,33 +0,0 @@ -name: Lint - -on: - push: - branches: - - "develop" - - "1.0-develop" - pull_request: - branches: - - "develop" - - "1.0-develop" - -jobs: - lint: - name: Lint - runs-on: ubuntu-20.04 - steps: - - name: Code Checkout - uses: actions/checkout@v3 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: "8.1" - extensions: bcmath, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip - tools: composer:v2 - coverage: none - - - name: Install dependencies - run: composer install --no-interaction --no-progress --no-suggest --prefer-dist - - - name: PHP CS Fixer - run: vendor/bin/php-cs-fixer fix --dry-run --diff diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 09ab86410..7c4a72bff 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -10,20 +10,20 @@ jobs: name: Release runs-on: ubuntu-20.04 steps: - - name: Code Checkout + - name: Code checkout uses: actions/checkout@v3 - name: Setup Node uses: actions/setup-node@v3 with: - node-version: 16 - cache: "yarn" + node-version: 18 + cache: yarn - name: Install dependencies run: yarn install --frozen-lockfile - name: Build - run: yarn build:production + run: yarn build - name: Create release branch and bump version env: @@ -41,7 +41,7 @@ jobs: - name: Create release archive run: | - rm -rf node_modules/ test/ codecov.yml CODE_OF_CONDUCT.md CONTRIBUTING.md phpunit.xml Vagrantfile + rm -rf node_modules/ tests/ CODE_OF_CONDUCT.md CONTRIBUTING.md phpstan.neon phpunit.xml tar -czf panel.tar.gz * .env.example .eslintignore .eslintrc.js - name: Extract changelog @@ -58,7 +58,7 @@ jobs: echo -e "\n#### SHA256 Checksum\n\n\`\`\`\n$SUM\n\`\`\`\n" >> ./RELEASE_CHANGELOG echo $SUM > checksum.txt - - name: Create Release + - name: Create release id: create_release uses: actions/create-release@v1 env: diff --git a/.github/workflows/ui.yaml b/.github/workflows/ui.yaml index e743de466..e61696c1c 100644 --- a/.github/workflows/ui.yaml +++ b/.github/workflows/ui.yaml @@ -11,28 +11,47 @@ on: - "1.0-develop" jobs: - build-and-test: - name: Build and Test + lint: + name: Lint runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - node-version: [16, 18] steps: - - name: Code Checkout + - name: Code checkout uses: actions/checkout@v3 - name: Setup Node uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} - cache: "yarn" + node-version: 18 + cache: yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Lint + run: yarn run lint + + tests: + name: Tests + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + node: [16, 18] + steps: + - name: Code checkout + uses: actions/checkout@v3 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + cache: yarn - name: Install dependencies run: yarn install --frozen-lockfile - name: Build - run: yarn build + run: yarn run build - name: Tests - run: yarn test + run: yarn run test diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index bcc636b5c..00cc8615e 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -25,7 +25,7 @@ use Pterodactyl\Exceptions\Repository\RecordNotFoundException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; -class Handler extends ExceptionHandler +final class Handler extends ExceptionHandler { /** * The validation parser in Laravel formats custom rules using the class name diff --git a/app/Http/Controllers/Admin/ApiController.php b/app/Http/Controllers/Admin/ApiController.php index 02ad6e540..247aaee00 100644 --- a/app/Http/Controllers/Admin/ApiController.php +++ b/app/Http/Controllers/Admin/ApiController.php @@ -9,7 +9,6 @@ use Pterodactyl\Models\ApiKey; use Illuminate\Http\RedirectResponse; use Prologue\Alerts\AlertsMessageBag; use Pterodactyl\Services\Acl\Api\AdminAcl; -use Illuminate\View\Factory as ViewFactory; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Services\Api\KeyCreationService; use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface; @@ -23,8 +22,7 @@ class ApiController extends Controller public function __construct( private AlertsMessageBag $alert, private ApiKeyRepositoryInterface $repository, - private KeyCreationService $keyCreationService, - private ViewFactory $view, + private KeyCreationService $keyCreationService ) { } @@ -33,7 +31,7 @@ class ApiController extends Controller */ public function index(Request $request): View { - return $this->view->make('admin.api.index', [ + return view('admin.api.index', [ 'keys' => $this->repository->getApplicationKeys($request->user()), ]); } @@ -48,7 +46,7 @@ class ApiController extends Controller $resources = AdminAcl::getResourceList(); sort($resources); - return $this->view->make('admin.api.new', [ + return view('admin.api.new', [ 'resources' => $resources, 'permissions' => [ 'r' => AdminAcl::READ, diff --git a/app/Http/Controllers/Admin/BaseController.php b/app/Http/Controllers/Admin/BaseController.php index 53f53ce54..2b6933074 100644 --- a/app/Http/Controllers/Admin/BaseController.php +++ b/app/Http/Controllers/Admin/BaseController.php @@ -3,7 +3,6 @@ namespace Pterodactyl\Http\Controllers\Admin; use Illuminate\View\View; -use Illuminate\View\Factory as ViewFactory; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Services\Helpers\SoftwareVersionService; @@ -12,7 +11,7 @@ class BaseController extends Controller /** * BaseController constructor. */ - public function __construct(private SoftwareVersionService $version, private ViewFactory $view) + public function __construct(private SoftwareVersionService $version) { } @@ -21,6 +20,6 @@ class BaseController extends Controller */ public function index(): View { - return $this->view->make('admin.index', ['version' => $this->version]); + return view('admin.index', ['version' => $this->version]); } } diff --git a/app/Http/Controllers/Admin/DatabaseController.php b/app/Http/Controllers/Admin/DatabaseController.php index e0dc0dc57..dc436ffaa 100644 --- a/app/Http/Controllers/Admin/DatabaseController.php +++ b/app/Http/Controllers/Admin/DatabaseController.php @@ -8,7 +8,6 @@ use Illuminate\View\View; use Pterodactyl\Models\DatabaseHost; use Illuminate\Http\RedirectResponse; use Prologue\Alerts\AlertsMessageBag; -use Illuminate\View\Factory as ViewFactory; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Services\Databases\Hosts\HostUpdateService; use Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest; @@ -30,8 +29,7 @@ class DatabaseController extends Controller private HostCreationService $creationService, private HostDeletionService $deletionService, private HostUpdateService $updateService, - private LocationRepositoryInterface $locationRepository, - private ViewFactory $view + private LocationRepositoryInterface $locationRepository ) { } @@ -40,7 +38,7 @@ class DatabaseController extends Controller */ public function index(): View { - return $this->view->make('admin.databases.index', [ + return view('admin.databases.index', [ 'locations' => $this->locationRepository->getAllWithNodes(), 'hosts' => $this->repository->getWithViewDetails(), ]); @@ -53,7 +51,7 @@ class DatabaseController extends Controller */ public function view(int $host): View { - return $this->view->make('admin.databases.view', [ + return view('admin.databases.view', [ 'locations' => $this->locationRepository->getAllWithNodes(), 'host' => $this->repository->find($host), 'databases' => $this->databaseRepository->getDatabasesForHost($host), diff --git a/app/Http/Controllers/Admin/LocationController.php b/app/Http/Controllers/Admin/LocationController.php index ea01cbaa9..41ed581db 100644 --- a/app/Http/Controllers/Admin/LocationController.php +++ b/app/Http/Controllers/Admin/LocationController.php @@ -35,7 +35,7 @@ class LocationController extends Controller */ public function index(): View { - return $this->view->make('admin.locations.index', [ + return view('admin.locations.index', [ 'locations' => $this->repository->getAllWithDetails(), ]); } @@ -47,7 +47,7 @@ class LocationController extends Controller */ public function view(int $id): View { - return $this->view->make('admin.locations.view', [ + return view('admin.locations.view', [ 'location' => $this->repository->getWithNodes($id), ]); } diff --git a/app/Http/Controllers/Admin/MountController.php b/app/Http/Controllers/Admin/MountController.php index 097ad6690..8f4138989 100644 --- a/app/Http/Controllers/Admin/MountController.php +++ b/app/Http/Controllers/Admin/MountController.php @@ -37,7 +37,7 @@ class MountController extends Controller */ public function index(): View { - return $this->view->make('admin.mounts.index', [ + return view('admin.mounts.index', [ 'mounts' => $this->repository->getAllWithDetails(), ]); } @@ -52,7 +52,7 @@ class MountController extends Controller $nests = Nest::query()->with('eggs')->get(); $locations = Location::query()->with('nodes')->get(); - return $this->view->make('admin.mounts.view', [ + return view('admin.mounts.view', [ 'mount' => $this->repository->getWithRelations($id), 'nests' => $nests, 'locations' => $locations, diff --git a/app/Http/Controllers/Admin/Nests/EggController.php b/app/Http/Controllers/Admin/Nests/EggController.php index 010c28af0..1efccfd5d 100644 --- a/app/Http/Controllers/Admin/Nests/EggController.php +++ b/app/Http/Controllers/Admin/Nests/EggController.php @@ -42,7 +42,7 @@ class EggController extends Controller $nests = $this->nestRepository->getWithEggs(); JavaScript::put(['nests' => $nests->keyBy('id')]); - return $this->view->make('admin.eggs.new', ['nests' => $nests]); + return view('admin.eggs.new', ['nests' => $nests]); } /** @@ -67,7 +67,7 @@ class EggController extends Controller */ public function view(Egg $egg): View { - return $this->view->make('admin.eggs.view', [ + return view('admin.eggs.view', [ 'egg' => $egg, 'images' => array_map( fn ($key, $value) => $key === $value ? $value : "$key|$value", diff --git a/app/Http/Controllers/Admin/Nests/EggScriptController.php b/app/Http/Controllers/Admin/Nests/EggScriptController.php index 4f997e5a8..b68a211ac 100644 --- a/app/Http/Controllers/Admin/Nests/EggScriptController.php +++ b/app/Http/Controllers/Admin/Nests/EggScriptController.php @@ -41,7 +41,7 @@ class EggScriptController extends Controller ['copy_script_from', '=', $egg->id], ]); - return $this->view->make('admin.eggs.scripts', [ + return view('admin.eggs.scripts', [ 'copyFromOptions' => $copy, 'relyOnScript' => $rely, 'egg' => $egg, diff --git a/app/Http/Controllers/Admin/Nests/EggVariableController.php b/app/Http/Controllers/Admin/Nests/EggVariableController.php index 40274b323..c94a8dc28 100644 --- a/app/Http/Controllers/Admin/Nests/EggVariableController.php +++ b/app/Http/Controllers/Admin/Nests/EggVariableController.php @@ -39,7 +39,7 @@ class EggVariableController extends Controller { $egg = $this->repository->getWithVariables($egg); - return $this->view->make('admin.eggs.variables', ['egg' => $egg]); + return view('admin.eggs.variables', ['egg' => $egg]); } /** diff --git a/app/Http/Controllers/Admin/Nests/NestController.php b/app/Http/Controllers/Admin/Nests/NestController.php index 037dd0943..fb24f1069 100644 --- a/app/Http/Controllers/Admin/Nests/NestController.php +++ b/app/Http/Controllers/Admin/Nests/NestController.php @@ -35,7 +35,7 @@ class NestController extends Controller */ public function index(): View { - return $this->view->make('admin.nests.index', [ + return view('admin.nests.index', [ 'nests' => $this->repository->getWithCounts(), ]); } @@ -45,7 +45,7 @@ class NestController extends Controller */ public function create(): View { - return $this->view->make('admin.nests.new'); + return view('admin.nests.new'); } /** @@ -68,7 +68,7 @@ class NestController extends Controller */ public function view(int $nest): View { - return $this->view->make('admin.nests.view', [ + return view('admin.nests.view', [ 'nest' => $this->repository->getWithEggServers($nest), ]); } diff --git a/app/Http/Controllers/Admin/Nodes/NodeController.php b/app/Http/Controllers/Admin/Nodes/NodeController.php index d80df6c80..793677240 100644 --- a/app/Http/Controllers/Admin/Nodes/NodeController.php +++ b/app/Http/Controllers/Admin/Nodes/NodeController.php @@ -7,17 +7,9 @@ use Illuminate\Http\Request; use Pterodactyl\Models\Node; use Spatie\QueryBuilder\QueryBuilder; use Pterodactyl\Http\Controllers\Controller; -use Illuminate\Contracts\View\Factory as ViewFactory; class NodeController extends Controller { - /** - * NodeController constructor. - */ - public function __construct(private ViewFactory $view) - { - } - /** * Returns a listing of nodes on the system. */ @@ -30,6 +22,6 @@ class NodeController extends Controller ->allowedSorts(['id']) ->paginate(25); - return $this->view->make('admin.nodes.index', ['nodes' => $nodes]); + return view('admin.nodes.index', ['nodes' => $nodes]); } } diff --git a/app/Http/Controllers/Admin/Nodes/NodeViewController.php b/app/Http/Controllers/Admin/Nodes/NodeViewController.php index 673890323..0ec60a7a0 100644 --- a/app/Http/Controllers/Admin/Nodes/NodeViewController.php +++ b/app/Http/Controllers/Admin/Nodes/NodeViewController.php @@ -8,13 +8,11 @@ use Pterodactyl\Models\Node; use Illuminate\Support\Collection; use Pterodactyl\Models\Allocation; use Pterodactyl\Http\Controllers\Controller; -use Illuminate\Contracts\View\Factory as ViewFactory; use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Repositories\Eloquent\ServerRepository; use Pterodactyl\Traits\Controllers\JavascriptInjection; use Pterodactyl\Services\Helpers\SoftwareVersionService; use Pterodactyl\Repositories\Eloquent\LocationRepository; -use Pterodactyl\Repositories\Eloquent\AllocationRepository; class NodeViewController extends Controller { @@ -24,12 +22,10 @@ class NodeViewController extends Controller * NodeViewController constructor. */ public function __construct( - private AllocationRepository $allocationRepository, private LocationRepository $locationRepository, private NodeRepository $repository, private ServerRepository $serverRepository, - private SoftwareVersionService $versionService, - private ViewFactory $view + private SoftwareVersionService $versionService ) { } @@ -40,7 +36,7 @@ class NodeViewController extends Controller { $node = $this->repository->loadLocationAndServerCount($node); - return $this->view->make('admin.nodes.view.index', [ + return view('admin.nodes.view.index', [ 'node' => $node, 'stats' => $this->repository->getUsageStats($node), 'version' => $this->versionService, @@ -52,7 +48,7 @@ class NodeViewController extends Controller */ public function settings(Request $request, Node $node): View { - return $this->view->make('admin.nodes.view.settings', [ + return view('admin.nodes.view.settings', [ 'node' => $node, 'locations' => $this->locationRepository->all(), ]); @@ -63,7 +59,7 @@ class NodeViewController extends Controller */ public function configuration(Request $request, Node $node): View { - return $this->view->make('admin.nodes.view.configuration', compact('node')); + return view('admin.nodes.view.configuration', compact('node')); } /** @@ -75,7 +71,7 @@ class NodeViewController extends Controller $this->plainInject(['node' => Collection::wrap($node)->only(['id'])]); - return $this->view->make('admin.nodes.view.allocation', [ + return view('admin.nodes.view.allocation', [ 'node' => $node, 'allocations' => Allocation::query()->where('node_id', $node->id) ->groupBy('ip') @@ -94,7 +90,7 @@ class NodeViewController extends Controller ->only(['scheme', 'fqdn', 'daemonListen', 'daemon_token_id', 'daemon_token']), ]); - return $this->view->make('admin.nodes.view.servers', [ + return view('admin.nodes.view.servers', [ 'node' => $node, 'servers' => $this->serverRepository->loadAllServersForNode($node->id, 25), ]); diff --git a/app/Http/Controllers/Admin/NodesController.php b/app/Http/Controllers/Admin/NodesController.php index 573a1d9f8..6d7cba7ff 100644 --- a/app/Http/Controllers/Admin/NodesController.php +++ b/app/Http/Controllers/Admin/NodesController.php @@ -60,7 +60,7 @@ class NodesController extends Controller return redirect()->route('admin.locations'); } - return $this->view->make('admin.nodes.new', ['locations' => $locations]); + return view('admin.nodes.new', ['locations' => $locations]); } /** diff --git a/app/Http/Controllers/Admin/Servers/CreateServerController.php b/app/Http/Controllers/Admin/Servers/CreateServerController.php index c7a1653ad..4ba37411b 100644 --- a/app/Http/Controllers/Admin/Servers/CreateServerController.php +++ b/app/Http/Controllers/Admin/Servers/CreateServerController.php @@ -4,11 +4,11 @@ namespace Pterodactyl\Http\Controllers\Admin\Servers; use JavaScript; use Illuminate\View\View; +use Pterodactyl\Models\Nest; use Pterodactyl\Models\Node; use Pterodactyl\Models\Location; use Illuminate\Http\RedirectResponse; use Prologue\Alerts\AlertsMessageBag; -use Illuminate\View\Factory as ViewFactory; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Repositories\Eloquent\NestRepository; use Pterodactyl\Repositories\Eloquent\NodeRepository; @@ -24,8 +24,7 @@ class CreateServerController extends Controller private AlertsMessageBag $alert, private NestRepository $nestRepository, private NodeRepository $nodeRepository, - private ServerCreationService $creationService, - private ViewFactory $view + private ServerCreationService $creationService ) { } @@ -47,14 +46,14 @@ class CreateServerController extends Controller JavaScript::put([ 'nodeData' => $this->nodeRepository->getNodesForServerCreation(), - 'nests' => $nests->map(function ($item) { + 'nests' => $nests->map(function (Nest $item) { return array_merge($item->toArray(), [ 'eggs' => $item->eggs->keyBy('id')->toArray(), ]); })->keyBy('id'), ]); - return $this->view->make('admin.servers.new', [ + return view('admin.servers.new', [ 'locations' => Location::all(), 'nests' => $nests, ]); diff --git a/app/Http/Controllers/Admin/Servers/ServerController.php b/app/Http/Controllers/Admin/Servers/ServerController.php index 430c3f2b9..80de68ef9 100644 --- a/app/Http/Controllers/Admin/Servers/ServerController.php +++ b/app/Http/Controllers/Admin/Servers/ServerController.php @@ -9,17 +9,9 @@ use Spatie\QueryBuilder\QueryBuilder; use Spatie\QueryBuilder\AllowedFilter; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Models\Filters\AdminServerFilter; -use Illuminate\Contracts\View\Factory as ViewFactory; class ServerController extends Controller { - /** - * ServerController constructor. - */ - public function __construct(private ViewFactory $view) - { - } - /** * Returns all the servers that exist on the system using a paginated result set. If * a query is passed along in the request it is also passed to the repository function. @@ -33,6 +25,6 @@ class ServerController extends Controller ]) ->paginate(config()->get('pterodactyl.paginate.admin.servers')); - return $this->view->make('admin.servers.index', ['servers' => $servers]); + return view('admin.servers.index', ['servers' => $servers]); } } diff --git a/app/Http/Controllers/Admin/Servers/ServerTransferController.php b/app/Http/Controllers/Admin/Servers/ServerTransferController.php index 8941ce10c..6d9496350 100644 --- a/app/Http/Controllers/Admin/Servers/ServerTransferController.php +++ b/app/Http/Controllers/Admin/Servers/ServerTransferController.php @@ -4,6 +4,7 @@ namespace Pterodactyl\Http\Controllers\Admin\Servers; use Carbon\CarbonImmutable; use Illuminate\Http\Request; +use Pterodactyl\Models\Node; use Pterodactyl\Models\Server; use Illuminate\Http\RedirectResponse; use Prologue\Alerts\AlertsMessageBag; @@ -11,7 +12,6 @@ use Pterodactyl\Models\ServerTransfer; use Illuminate\Database\ConnectionInterface; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Services\Nodes\NodeJWTService; -use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Repositories\Wings\DaemonTransferRepository; use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; @@ -25,8 +25,7 @@ class ServerTransferController extends Controller private AllocationRepositoryInterface $allocationRepository, private ConnectionInterface $connection, private DaemonTransferRepository $daemonTransferRepository, - private NodeJWTService $nodeJWTService, - private NodeRepository $nodeRepository + private NodeJWTService $nodeJWTService ) { } @@ -48,7 +47,7 @@ class ServerTransferController extends Controller $additional_allocations = array_map('intval', $validatedData['allocation_additional'] ?? []); // Check if the node is viable for the transfer. - $node = $this->nodeRepository->getNodeWithResourceUsage($node_id); + $node = Node::query()->findOrFail($node_id); if (!$node->isViable($server->memory, $server->disk)) { $this->alert->danger(trans('admin/server.alerts.transfer_not_viable'))->flash(); @@ -58,7 +57,6 @@ class ServerTransferController extends Controller $server->validateTransferState(); $this->connection->transaction(function () use ($server, $node_id, $allocation_id, $additional_allocations) { - // Create a new ServerTransfer entry. $transfer = new ServerTransfer(); $transfer->server_id = $server->id; @@ -66,7 +64,7 @@ class ServerTransferController extends Controller $transfer->new_node = $node_id; $transfer->old_allocation = $server->allocation_id; $transfer->new_allocation = $allocation_id; - $transfer->old_additional_allocations = $server->allocations->where('id', '!=', $server->allocation_id)->pluck('id'); + $transfer->old_additional_allocations = $server->allocations->where('id', '!=', $server->allocation_id)->pluck('id')->all(); $transfer->new_additional_allocations = $additional_allocations; $transfer->save(); diff --git a/app/Http/Controllers/Admin/Servers/ServerViewController.php b/app/Http/Controllers/Admin/Servers/ServerViewController.php index 7cf64a2f5..3e662d479 100644 --- a/app/Http/Controllers/Admin/Servers/ServerViewController.php +++ b/app/Http/Controllers/Admin/Servers/ServerViewController.php @@ -10,11 +10,9 @@ use Pterodactyl\Models\Server; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Services\Servers\EnvironmentService; -use Illuminate\Contracts\View\Factory as ViewFactory; use Pterodactyl\Repositories\Eloquent\NestRepository; use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Repositories\Eloquent\MountRepository; -use Pterodactyl\Repositories\Eloquent\ServerRepository; use Pterodactyl\Traits\Controllers\JavascriptInjection; use Pterodactyl\Repositories\Eloquent\LocationRepository; use Pterodactyl\Repositories\Eloquent\DatabaseHostRepository; @@ -32,9 +30,7 @@ class ServerViewController extends Controller private MountRepository $mountRepository, private NestRepository $nestRepository, private NodeRepository $nodeRepository, - private ServerRepository $repository, - private EnvironmentService $environmentService, - private ViewFactory $view + private EnvironmentService $environmentService ) { } @@ -43,7 +39,7 @@ class ServerViewController extends Controller */ public function index(Request $request, Server $server): View { - return $this->view->make('admin.servers.view.index', compact('server')); + return view('admin.servers.view.index', compact('server')); } /** @@ -51,7 +47,7 @@ class ServerViewController extends Controller */ public function details(Request $request, Server $server): View { - return $this->view->make('admin.servers.view.details', compact('server')); + return view('admin.servers.view.details', compact('server')); } /** @@ -61,7 +57,7 @@ class ServerViewController extends Controller { $allocations = $server->node->allocations->toBase(); - return $this->view->make('admin.servers.view.build', [ + return view('admin.servers.view.build', [ 'server' => $server, 'assigned' => $allocations->where('server_id', $server->id)->sortBy('port')->sortBy('ip'), 'unassigned' => $allocations->where('server_id', null)->sortBy('port')->sortBy('ip'), @@ -88,7 +84,7 @@ class ServerViewController extends Controller })->keyBy('id'), ]); - return $this->view->make('admin.servers.view.startup', compact('server', 'nests')); + return view('admin.servers.view.startup', compact('server', 'nests')); } /** @@ -96,7 +92,7 @@ class ServerViewController extends Controller */ public function database(Request $request, Server $server): View { - return $this->view->make('admin.servers.view.database', [ + return view('admin.servers.view.database', [ 'hosts' => $this->databaseHostRepository->all(), 'server' => $server, ]); @@ -109,7 +105,7 @@ class ServerViewController extends Controller { $server->load('mounts'); - return $this->view->make('admin.servers.view.mounts', [ + return view('admin.servers.view.mounts', [ 'mounts' => $this->mountRepository->getMountListForServer($server), 'server' => $server, ]); @@ -138,7 +134,7 @@ class ServerViewController extends Controller 'nodeData' => $this->nodeRepository->getNodesForServerCreation(), ]); - return $this->view->make('admin.servers.view.manage', [ + return view('admin.servers.view.manage', [ 'server' => $server, 'locations' => $this->locationRepository->all(), 'canTransfer' => $canTransfer, @@ -150,6 +146,6 @@ class ServerViewController extends Controller */ public function delete(Request $request, Server $server): View { - return $this->view->make('admin.servers.view.delete', compact('server')); + return view('admin.servers.view.delete', compact('server')); } } diff --git a/app/Http/Controllers/Admin/Settings/AdvancedController.php b/app/Http/Controllers/Admin/Settings/AdvancedController.php index bf6883232..20f8f3c03 100644 --- a/app/Http/Controllers/Admin/Settings/AdvancedController.php +++ b/app/Http/Controllers/Admin/Settings/AdvancedController.php @@ -6,7 +6,6 @@ use Illuminate\View\View; use Illuminate\Http\RedirectResponse; use Prologue\Alerts\AlertsMessageBag; use Illuminate\Contracts\Console\Kernel; -use Illuminate\View\Factory as ViewFactory; use Pterodactyl\Http\Controllers\Controller; use Illuminate\Contracts\Config\Repository as ConfigRepository; use Pterodactyl\Contracts\Repository\SettingsRepositoryInterface; @@ -21,8 +20,7 @@ class AdvancedController extends Controller private AlertsMessageBag $alert, private ConfigRepository $config, private Kernel $kernel, - private SettingsRepositoryInterface $settings, - private ViewFactory $view + private SettingsRepositoryInterface $settings ) { } @@ -39,7 +37,7 @@ class AdvancedController extends Controller $showRecaptchaWarning = true; } - return $this->view->make('admin.settings.advanced', [ + return view('admin.settings.advanced', [ 'showRecaptchaWarning' => $showRecaptchaWarning, ]); } diff --git a/app/Http/Controllers/Admin/Settings/IndexController.php b/app/Http/Controllers/Admin/Settings/IndexController.php index eabede932..ca92e7d03 100644 --- a/app/Http/Controllers/Admin/Settings/IndexController.php +++ b/app/Http/Controllers/Admin/Settings/IndexController.php @@ -6,7 +6,6 @@ use Illuminate\View\View; use Illuminate\Http\RedirectResponse; use Prologue\Alerts\AlertsMessageBag; use Illuminate\Contracts\Console\Kernel; -use Illuminate\View\Factory as ViewFactory; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Traits\Helpers\AvailableLanguages; use Pterodactyl\Services\Helpers\SoftwareVersionService; @@ -24,8 +23,7 @@ class IndexController extends Controller private AlertsMessageBag $alert, private Kernel $kernel, private SettingsRepositoryInterface $settings, - private SoftwareVersionService $versionService, - private ViewFactory $view + private SoftwareVersionService $versionService ) { } @@ -34,7 +32,7 @@ class IndexController extends Controller */ public function index(): View { - return $this->view->make('admin.settings.index', [ + return view('admin.settings.index', [ 'version' => $this->versionService, 'languages' => $this->getAvailableLanguages(true), ]); diff --git a/app/Http/Controllers/Admin/Settings/MailController.php b/app/Http/Controllers/Admin/Settings/MailController.php index 2db87fd58..8c9365641 100644 --- a/app/Http/Controllers/Admin/Settings/MailController.php +++ b/app/Http/Controllers/Admin/Settings/MailController.php @@ -8,7 +8,6 @@ use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Contracts\Console\Kernel; use Pterodactyl\Notifications\MailTested; -use Illuminate\View\Factory as ViewFactory; use Illuminate\Support\Facades\Notification; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Http\Controllers\Controller; @@ -27,8 +26,7 @@ class MailController extends Controller private ConfigRepository $config, private Encrypter $encrypter, private Kernel $kernel, - private SettingsRepositoryInterface $settings, - private ViewFactory $view + private SettingsRepositoryInterface $settings ) { } @@ -38,7 +36,7 @@ class MailController extends Controller */ public function index(): View { - return $this->view->make('admin.settings.mail', [ + return view('admin.settings.mail', [ 'disabled' => $this->config->get('mail.default') !== 'smtp', ]); } diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 1d6db6569..ef22189d4 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -6,13 +6,13 @@ use Illuminate\View\View; use Illuminate\Http\Request; use Pterodactyl\Models\User; use Pterodactyl\Models\Model; -use Illuminate\Support\Collection; use Illuminate\Http\RedirectResponse; use Prologue\Alerts\AlertsMessageBag; use Spatie\QueryBuilder\QueryBuilder; use Illuminate\View\Factory as ViewFactory; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Http\Controllers\Controller; +use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Contracts\Translation\Translator; use Pterodactyl\Services\Users\UserUpdateService; use Pterodactyl\Traits\Helpers\AvailableLanguages; @@ -57,7 +57,7 @@ class UserController extends Controller ->allowedSorts(['id', 'uuid']) ->paginate(50); - return $this->view->make('admin.users.index', ['users' => $users]); + return view('admin.users.index', ['users' => $users]); } /** @@ -65,7 +65,7 @@ class UserController extends Controller */ public function create(): View { - return $this->view->make('admin.users.new', [ + return view('admin.users.new', [ 'languages' => $this->getAvailableLanguages(true), ]); } @@ -75,7 +75,7 @@ class UserController extends Controller */ public function view(User $user): View { - return $this->view->make('admin.users.view', [ + return view('admin.users.view', [ 'user' => $user, 'languages' => $this->getAvailableLanguages(true), ]); @@ -132,22 +132,13 @@ class UserController extends Controller /** * Get a JSON response of users on the system. */ - public function json(Request $request): Model|Collection + public function json(Request $request): Model|LengthAwarePaginator { - $users = QueryBuilder::for(User::query())->allowedFilters(['email'])->paginate(25); - // Handle single user requests. if ($request->query('user_id')) { - $user = User::query()->findOrFail($request->input('user_id')); - $user->md5 = md5(strtolower($user->email)); - - return $user; + return User::query()->findOrFail($request->input('user_id')); } - return $users->map(function ($item) { - $item->md5 = md5(strtolower($item->email)); - - return $item; - }); + return QueryBuilder::for(User::query())->allowedFilters(['email'])->paginate(25); } } diff --git a/app/Http/Controllers/Api/Client/Servers/StartupController.php b/app/Http/Controllers/Api/Client/Servers/StartupController.php index 9548be25e..b674145ff 100644 --- a/app/Http/Controllers/Api/Client/Servers/StartupController.php +++ b/app/Http/Controllers/Api/Client/Servers/StartupController.php @@ -52,7 +52,6 @@ class StartupController extends ClientApiController */ public function update(UpdateStartupVariableRequest $request, Server $server): array { - /** @var \Pterodactyl\Models\EggVariable $variable */ $variable = $server->variables()->where('env_variable', $request->input('key'))->first(); $original = $variable->server_value; @@ -62,6 +61,8 @@ class StartupController extends ClientApiController throw new BadRequestHttpException('The environment variable you are trying to edit is read-only.'); } + /* @var \Pterodactyl\Models\EggVariable $variable */ + // Revalidate the variable value using the egg variable specific validation rules for it. $this->validate($request, ['value' => $variable->rules]); diff --git a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php index 8ce88e89e..8d8b0de92 100644 --- a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php +++ b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php @@ -3,6 +3,7 @@ namespace Pterodactyl\Http\Controllers\Api\Remote\Servers; use Illuminate\Http\Request; +use Pterodactyl\Models\Backup; use Pterodactyl\Models\Server; use Illuminate\Http\JsonResponse; use Pterodactyl\Facades\Activity; @@ -98,9 +99,11 @@ class ServerDetailsController extends Controller if ($subject = $activity->subjects->where('subject_type', 'backup')->first()) { // Just create a new audit entry for this event and update the server state // so that power actions, file management, and backups can resume as normal. + /** @var Backup $actualSubject */ + $actualSubject = $subject->subject; Activity::event('server:backup.restore-failed') - ->subject($server, $subject->subject) - ->property('name', $subject->subject->name) + ->subject($server, $actualSubject) + ->property('name', $actualSubject->name) ->log(); } } diff --git a/app/Http/Controllers/Auth/AbstractLoginController.php b/app/Http/Controllers/Auth/AbstractLoginController.php index f07282fba..74e7a9aa3 100644 --- a/app/Http/Controllers/Auth/AbstractLoginController.php +++ b/app/Http/Controllers/Auth/AbstractLoginController.php @@ -49,7 +49,9 @@ abstract class AbstractLoginController extends Controller /** * Get the failed login response instance. * - * @throws \Pterodactyl\Exceptions\DisplayException + * @return never + * + * @throws DisplayException */ protected function sendFailedLoginResponse(Request $request, Authenticatable $user = null, string $message = null) { diff --git a/app/Http/Controllers/Auth/LoginCheckpointController.php b/app/Http/Controllers/Auth/LoginCheckpointController.php index af05c55ef..82580edc0 100644 --- a/app/Http/Controllers/Auth/LoginCheckpointController.php +++ b/app/Http/Controllers/Auth/LoginCheckpointController.php @@ -72,7 +72,7 @@ class LoginCheckpointController extends AbstractLoginController } else { $decrypted = $this->encrypter->decrypt($user->totp_secret); - if ($this->google2FA->verifyKey($decrypted, (string) $request->input('authentication_code') ?? '', config('pterodactyl.auth.2fa.window'))) { + if ($this->google2FA->verifyKey($decrypted, $request->input('authentication_code') ?? '', config('pterodactyl.auth.2fa.window'))) { Event::dispatch(new ProvidedAuthenticationToken($user)); return $this->sendLoginResponse($user, $request); diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 2dbb34ee3..49a17378d 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -9,19 +9,10 @@ use Pterodactyl\Models\User; use Illuminate\Http\JsonResponse; use Pterodactyl\Facades\Activity; use Illuminate\Contracts\View\View; -use Illuminate\Contracts\View\Factory as ViewFactory; use Illuminate\Database\Eloquent\ModelNotFoundException; class LoginController extends AbstractLoginController { - /** - * LoginController constructor. - */ - public function __construct(private ViewFactory $view) - { - parent::__construct(); - } - /** * Handle all incoming requests for the authentication routes and render the * base authentication view component. React will take over at this point and @@ -29,7 +20,7 @@ class LoginController extends AbstractLoginController */ public function index(): View { - return $this->view->make('templates/auth.core'); + return view('templates/auth.core'); } /** diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index 3325a1e6b..9b22f6f98 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -3,6 +3,7 @@ namespace Pterodactyl\Http\Controllers\Auth; use Illuminate\Support\Str; +use Pterodactyl\Models\User; use Illuminate\Http\JsonResponse; use Illuminate\Contracts\Hashing\Hasher; use Illuminate\Support\Facades\Password; @@ -67,13 +68,12 @@ class ResetPasswordController extends Controller * account do not automatically log them in. In those cases, send the user back to the login * form with a note telling them their password was changed and to log back in. * - * @param \Illuminate\Contracts\Auth\CanResetPassword|\Pterodactyl\Models\User $user * @param string $password * * @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - protected function resetPassword($user, $password) + protected function resetPassword(User $user, $password) { $user = $this->userRepository->update($user->id, [ 'password' => $this->hasher->make($password), diff --git a/app/Http/Controllers/Base/IndexController.php b/app/Http/Controllers/Base/IndexController.php index fecaa91a3..ffa278b63 100644 --- a/app/Http/Controllers/Base/IndexController.php +++ b/app/Http/Controllers/Base/IndexController.php @@ -23,6 +23,6 @@ class IndexController extends Controller */ public function index(): View { - return $this->view->make('templates/base.core'); + return view('templates/base.core'); } } diff --git a/app/Http/Middleware/Api/Client/Server/ResourceBelongsToServer.php b/app/Http/Middleware/Api/Client/Server/ResourceBelongsToServer.php index 5d3530d86..337f4af71 100644 --- a/app/Http/Middleware/Api/Client/Server/ResourceBelongsToServer.php +++ b/app/Http/Middleware/Api/Client/Server/ResourceBelongsToServer.php @@ -29,11 +29,11 @@ class ResourceBelongsToServer public function handle(Request $request, Closure $next): mixed { $params = $request->route()->parameters(); - if (is_null($params) || !$params['server'] instanceof Server) { + if (!$params['server'] instanceof Server) { throw new InvalidArgumentException('This middleware cannot be used in a context that is missing a server in the parameters.'); } - /** @var \Pterodactyl\Models\Server $server */ + /** @var Server $server */ $server = $request->route()->parameter('server'); $exception = new NotFoundHttpException('The requested resource was not found for this server.'); foreach ($params as $key => $model) { @@ -45,6 +45,7 @@ class ResourceBelongsToServer continue; } + /** @var Allocation|Backup|Database|Schedule|Subuser $model */ switch (get_class($model)) { // All of these models use "server_id" as the field key for the server // they are assigned to, so the logic is identical for them all. @@ -71,6 +72,7 @@ class ResourceBelongsToServer // Tasks are special since they're (currently) the only item in the API // that requires something in addition to the server in order to be accessed. case Task::class: + /** @var Schedule $schedule */ $schedule = $request->route()->parameter('schedule'); if ($model->schedule_id !== $schedule->id || $schedule->server_id !== $server->id) { throw $exception; diff --git a/app/Http/Middleware/RequireTwoFactorAuthentication.php b/app/Http/Middleware/RequireTwoFactorAuthentication.php index e3307727f..cffcc5011 100644 --- a/app/Http/Middleware/RequireTwoFactorAuthentication.php +++ b/app/Http/Middleware/RequireTwoFactorAuthentication.php @@ -5,6 +5,7 @@ namespace Pterodactyl\Http\Middleware; use Closure; use Illuminate\Support\Str; use Illuminate\Http\Request; +use Pterodactyl\Models\User; use Prologue\Alerts\AlertsMessageBag; use Pterodactyl\Exceptions\Http\TwoFactorAuthRequiredException; @@ -36,12 +37,17 @@ class RequireTwoFactorAuthentication */ public function handle(Request $request, Closure $next): mixed { - /** @var \Pterodactyl\Models\User $user */ + /** @var User $user */ $user = $request->user(); $uri = rtrim($request->getRequestUri(), '/') . '/'; $current = $request->route()->getName(); - if (!$user || Str::startsWith($uri, ['/auth/']) || Str::startsWith($current, ['auth.', 'account.'])) { + // Must be logged in + if (!$user instanceof User) { + return $next($request); + } + + if (Str::startsWith($uri, ['/auth/']) || Str::startsWith($current, ['auth.', 'account.'])) { return $next($request); } diff --git a/app/Http/Requests/Admin/LocationFormRequest.php b/app/Http/Requests/Admin/LocationFormRequest.php index b10e304a0..57fa0310b 100644 --- a/app/Http/Requests/Admin/LocationFormRequest.php +++ b/app/Http/Requests/Admin/LocationFormRequest.php @@ -12,7 +12,10 @@ class LocationFormRequest extends AdminFormRequest public function rules(): array { if ($this->method() === 'PATCH') { - return Location::getRulesForUpdate($this->route()->parameter('location')->id); + /** @var Location $location */ + $location = $this->route()->parameter('location'); + + return Location::getRulesForUpdate($location->id); } return Location::getRules(); diff --git a/app/Http/Requests/Admin/MountFormRequest.php b/app/Http/Requests/Admin/MountFormRequest.php index 074ea4a50..22b2475f4 100644 --- a/app/Http/Requests/Admin/MountFormRequest.php +++ b/app/Http/Requests/Admin/MountFormRequest.php @@ -12,7 +12,10 @@ class MountFormRequest extends AdminFormRequest public function rules(): array { if ($this->method() === 'PATCH') { - return Mount::getRulesForUpdate($this->route()->parameter('mount')->id); + /** @var Mount $mount */ + $mount = $this->route()->parameter('mount'); + + return Mount::getRulesForUpdate($mount->id); } return Mount::getRules(); diff --git a/app/Http/Requests/Api/Application/ApplicationApiRequest.php b/app/Http/Requests/Api/Application/ApplicationApiRequest.php index 2e0ed133a..082bc6921 100644 --- a/app/Http/Requests/Api/Application/ApplicationApiRequest.php +++ b/app/Http/Requests/Api/Application/ApplicationApiRequest.php @@ -29,7 +29,7 @@ abstract class ApplicationApiRequest extends FormRequest * Determine if the current user is authorized to perform * the requested action against the API. * - * @throws \Pterodactyl\Exceptions\PterodactylException + * @throws PterodactylException */ public function authorize(): bool { @@ -42,6 +42,7 @@ abstract class ApplicationApiRequest extends FormRequest return true; } + /** @var ApiKey $token */ if ($token->key_type === ApiKey::TYPE_ACCOUNT) { return true; } @@ -81,6 +82,7 @@ abstract class ApplicationApiRequest extends FormRequest */ public function parameter(string $key, string $expect) { + /** @var ApiKey $value */ $value = $this->route()->parameter($key); Assert::isInstanceOf($value, $expect); diff --git a/app/Http/Requests/Api/Application/Locations/UpdateLocationRequest.php b/app/Http/Requests/Api/Application/Locations/UpdateLocationRequest.php index ce42e6f05..b7acac978 100644 --- a/app/Http/Requests/Api/Application/Locations/UpdateLocationRequest.php +++ b/app/Http/Requests/Api/Application/Locations/UpdateLocationRequest.php @@ -11,7 +11,9 @@ class UpdateLocationRequest extends StoreLocationRequest */ public function rules(): array { - $locationId = $this->route()->parameter('location')->id; + /** @var Location $location */ + $location = $this->route()->parameter('location'); + $locationId = $location->id; return collect(Location::getRulesForUpdate($locationId))->only([ 'short', diff --git a/app/Http/Requests/Api/Application/Nodes/UpdateNodeRequest.php b/app/Http/Requests/Api/Application/Nodes/UpdateNodeRequest.php index 7133bd0b5..de6b7b45c 100644 --- a/app/Http/Requests/Api/Application/Nodes/UpdateNodeRequest.php +++ b/app/Http/Requests/Api/Application/Nodes/UpdateNodeRequest.php @@ -12,8 +12,9 @@ class UpdateNodeRequest extends StoreNodeRequest */ public function rules(array $rules = null): array { - $node = $this->route()->parameter('node')->id; + /** @var Node $node */ + $node = $this->route()->parameter('node'); - return parent::rules(Node::getRulesForUpdate($node)); + return parent::rules(Node::getRulesForUpdate($node->id)); } } diff --git a/app/Http/Requests/Api/Application/Servers/Databases/StoreServerDatabaseRequest.php b/app/Http/Requests/Api/Application/Servers/Databases/StoreServerDatabaseRequest.php index d53a0a75e..f52bed805 100644 --- a/app/Http/Requests/Api/Application/Servers/Databases/StoreServerDatabaseRequest.php +++ b/app/Http/Requests/Api/Application/Servers/Databases/StoreServerDatabaseRequest.php @@ -21,6 +21,7 @@ class StoreServerDatabaseRequest extends ApplicationApiRequest */ public function rules(): array { + /** @var Server $server */ $server = $this->route()->parameter('server'); return [ @@ -67,6 +68,7 @@ class StoreServerDatabaseRequest extends ApplicationApiRequest */ public function databaseName(): string { + /** @var Server $server */ $server = $this->route()->parameter('server'); Assert::isInstanceOf($server, Server::class); diff --git a/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php b/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php index be4f4a719..41569cfab 100644 --- a/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Databases/StoreDatabaseRequest.php @@ -21,6 +21,7 @@ class StoreDatabaseRequest extends ClientApiRequest implements ClientPermissions public function rules(): array { + /** @var Server $server */ $server = $this->route()->parameter('server'); Assert::isInstanceOf($server, Server::class); diff --git a/app/Http/Requests/Api/Client/Servers/Subusers/SubuserRequest.php b/app/Http/Requests/Api/Client/Servers/Subusers/SubuserRequest.php index 7c4fab9d2..1381e5cb9 100644 --- a/app/Http/Requests/Api/Client/Servers/Subusers/SubuserRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Subusers/SubuserRequest.php @@ -63,7 +63,6 @@ abstract class SubuserRequest extends ClientApiRequest // Otherwise, get the current subuser's permission set, and ensure that the // permissions they are trying to assign are not _more_ than the ones they // already have. - /** @var \Pterodactyl\Models\Subuser|null $subuser */ /** @var \Pterodactyl\Services\Servers\GetUserPermissionsService $service */ $service = $this->container->make(GetUserPermissionsService::class); diff --git a/app/Models/Egg.php b/app/Models/Egg.php index 31c3e3420..c33e5b194 100644 --- a/app/Models/Egg.php +++ b/app/Models/Egg.php @@ -26,9 +26,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property string|null $startup * @property bool $script_is_privileged * @property string|null $script_install - * @property string $script_entry - * @property string $script_container - * @property int|null $copy_script_from + * @property ?string $script_entry + * @property ?string $script_container + * @property ?int $copy_script_from * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at * @property string|null $copy_script_install diff --git a/app/Models/EggVariable.php b/app/Models/EggVariable.php index 8c34bb398..dbbf8e0bd 100644 --- a/app/Models/EggVariable.php +++ b/app/Models/EggVariable.php @@ -18,8 +18,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany; * @property \Carbon\CarbonImmutable $created_at * @property \Carbon\CarbonImmutable $updated_at * @property bool $required - * @property \Pterodactyl\Models\Egg $egg - * @property \Pterodactyl\Models\ServerVariable $serverVariable + * @property Egg $egg + * @property ServerVariable $serverVariable + * @property string $field_type * * The "server_value" variable is only present on the object if you've loaded this model * using the server relationship. diff --git a/app/Models/Model.php b/app/Models/Model.php index 2e371d9d9..34b856c38 100644 --- a/app/Models/Model.php +++ b/app/Models/Model.php @@ -155,6 +155,7 @@ abstract class Model extends IlluminateModel return; } + /** @var \Illuminate\Validation\Validator $validator */ $validator = $this->getValidator(); $validator->setData( // Trying to do self::toArray() here will leave out keys based on the whitelist/blacklist diff --git a/app/Models/Node.php b/app/Models/Node.php index 504a28c24..a1d9688f6 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -6,6 +6,7 @@ use Illuminate\Support\Str; use Symfony\Component\Yaml\Yaml; use Illuminate\Container\Container; use Illuminate\Notifications\Notifiable; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Contracts\Encryption\Encrypter; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -24,20 +25,24 @@ use Illuminate\Database\Eloquent\Relations\HasManyThrough; * @property bool $maintenance_mode * @property int $memory * @property int $memory_overallocate + * @property int $sum_memory * @property int $disk * @property int $disk_overallocate + * @property int $sum_disk * @property int $upload_size * @property string $daemon_token_id * @property string $daemon_token * @property int $daemonListen * @property int $daemonSFTP * @property string $daemonBase + * @property int $servers_count * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at - * @property \Pterodactyl\Models\Location $location - * @property \Pterodactyl\Models\Mount[]|\Illuminate\Database\Eloquent\Collection $mounts - * @property \Pterodactyl\Models\Server[]|\Illuminate\Database\Eloquent\Collection $servers - * @property \Pterodactyl\Models\Allocation[]|\Illuminate\Database\Eloquent\Collection $allocations + * @property Location $location + * @property int[]|\Illuminate\Support\Collection $ports + * @property Mount[]|Collection $mounts + * @property Server[]|Collection $servers + * @property Allocation[]|Collection $allocations */ class Node extends Model { @@ -220,11 +225,21 @@ class Node extends Model return $this->hasMany(Allocation::class); } + public function loadServerSums(): self + { + $this->loadSum('servers as sum_memory', 'memory'); + $this->loadSum('servers as sum_disk', 'disk'); + + return $this; + } + /** * Returns a boolean if the node is viable for an additional server to be placed on it. */ - public function isViable(int $memory, int $disk): bool + public function isViable(int $memory = 0, int $disk = 0): bool { + $this->loadServerSums(); + $memoryLimit = $this->memory * (1.0 + ($this->memory_overallocate / 100.0)); $diskLimit = $this->disk * (1.0 + ($this->disk_overallocate / 100.0)); diff --git a/app/Models/Setting.php b/app/Models/Setting.php index 52c7f1cff..ec85a2ecf 100644 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Models; +/** @property string $value */ class Setting extends Model { /** diff --git a/app/Models/User.php b/app/Models/User.php index eb3c15d22..bef6da781 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -11,6 +11,7 @@ use Illuminate\Notifications\Notifiable; use Illuminate\Database\Eloquent\Builder; use Pterodactyl\Models\Traits\HasAccessTokens; use Illuminate\Auth\Passwords\CanResetPassword; +use Illuminate\Database\Eloquent\Casts\Attribute; use Pterodactyl\Traits\Helpers\AvailableLanguages; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\Access\Authorizable; @@ -129,6 +130,10 @@ class User extends Model implements 'root_admin', ]; + protected $appends = [ + 'md5', + ]; + /** * Cast values to correct type. */ @@ -259,6 +264,13 @@ class User extends Model implements return $this->morphToMany(ActivityLog::class, 'subject', 'activity_log_subjects'); } + public function md5(): Attribute + { + return Attribute::make( + get: fn () => md5(strtolower($this->email)), + ); + } + /** * Returns all the servers that a user can access by way of being the owner of the * server, or because they are assigned as a subuser for that server. diff --git a/app/Notifications/ServerInstalled.php b/app/Notifications/ServerInstalled.php index 46f38ff84..3eb93e79d 100644 --- a/app/Notifications/ServerInstalled.php +++ b/app/Notifications/ServerInstalled.php @@ -26,12 +26,14 @@ class ServerInstalled extends Notification implements ShouldQueue, ReceivesEvent * Handle a direct call to this notification from the server installed event. This is configured * in the event service provider. */ - public function handle(Event|Installed $event): void + public function handle(Event|Installed $notification): void { - $event->server->loadMissing('user'); + abort_unless($notification instanceof Installed, 500); + /* @var Installed $notification */ + $notification->server->loadMissing('user'); - $this->server = $event->server; - $this->user = $event->server->user; + $this->server = $notification->server; + $this->user = $notification->server->user; // Since we are calling this notification directly from an event listener we need to fire off the dispatcher // to send the email now. Don't use send() or you'll end up firing off two different events. diff --git a/app/Repositories/Eloquent/EloquentRepository.php b/app/Repositories/Eloquent/EloquentRepository.php index a78295be4..ea636ce9c 100644 --- a/app/Repositories/Eloquent/EloquentRepository.php +++ b/app/Repositories/Eloquent/EloquentRepository.php @@ -78,6 +78,7 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf */ public function create(array $fields, bool $validate = true, bool $force = false): Model|bool { + /** @var \Pterodactyl\Models\Model $instance */ $instance = $this->getBuilder()->newModelInstance(); ($force) ? $instance->forceFill($fields) : $instance->fill($fields); @@ -163,6 +164,7 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf public function update(int $id, array $fields, bool $validate = true, bool $force = false): Model|bool { try { + /** @var \Pterodactyl\Models\Model $instance */ $instance = $this->getBuilder()->where('id', $id)->firstOrFail(); } catch (ModelNotFoundException) { throw new RecordNotFoundException(); diff --git a/app/Repositories/Eloquent/NodeRepository.php b/app/Repositories/Eloquent/NodeRepository.php index d7a3818f3..0ee703a79 100644 --- a/app/Repositories/Eloquent/NodeRepository.php +++ b/app/Repositories/Eloquent/NodeRepository.php @@ -21,11 +21,7 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa */ public function getUsageStats(Node $node): array { - $stats = $this->getBuilder() - ->selectRaw('COALESCE(SUM(servers.memory), 0) as sum_memory, COALESCE(SUM(servers.disk), 0) as sum_disk') - ->join('servers', 'servers.node_id', '=', 'nodes.id') - ->where('node_id', '=', $node->id) - ->first(); + $stats = $node->loadServerSums(); return Collection::make(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory]) ->mapWithKeys(function ($value, $key) use ($node) { @@ -53,9 +49,7 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa */ public function getUsageStatsRaw(Node $node): array { - $stats = $this->getBuilder()->select( - $this->getBuilder()->raw('COALESCE(SUM(servers.memory), 0) as sum_memory, COALESCE(SUM(servers.disk), 0) as sum_disk') - )->join('servers', 'servers.node_id', '=', 'nodes.id')->where('node_id', $node->id)->first(); + $stats = $node->loadServerSums(); return collect(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory])->mapWithKeys(function ($value, $key) use ($node) { $maxUsage = $node->{$key}; @@ -84,9 +78,7 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa // This is quite ugly and can probably be improved down the road. // And by probably, I mean it should. if (is_null($node->servers_count) || $refresh) { - $node->load('servers'); - $node->setRelation('servers_count', count($node->getRelation('servers'))); - unset($node->servers); + $node->loadCount('servers'); } return $node; @@ -135,18 +127,4 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa ]; })->values(); } - - /** - * Returns a node with the given id with the Node's resource usage. - */ - public function getNodeWithResourceUsage(int $node_id): Node - { - $instance = $this->getBuilder() - ->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemonListen', 'nodes.memory', 'nodes.disk', 'nodes.memory_overallocate', 'nodes.disk_overallocate']) - ->selectRaw('COALESCE(SUM(servers.memory), 0) as sum_memory, COALESCE(SUM(servers.disk), 0) as sum_disk') - ->leftJoin('servers', 'servers.node_id', '=', 'nodes.id') - ->where('nodes.id', $node_id); - - return $instance->first(); - } } diff --git a/app/Repositories/Eloquent/SettingsRepository.php b/app/Repositories/Eloquent/SettingsRepository.php index df22fce59..e8003129a 100644 --- a/app/Repositories/Eloquent/SettingsRepository.php +++ b/app/Repositories/Eloquent/SettingsRepository.php @@ -46,6 +46,7 @@ class SettingsRepository extends EloquentRepository implements SettingsRepositor return value($default); } + /** @var Setting $instance */ $instance = $this->getBuilder()->where('key', $key)->first(); if (is_null($instance)) { self::$databaseMiss[$key] = true; diff --git a/app/Rules/Fqdn.php b/app/Rules/Fqdn.php index 47baf510d..915ca4015 100644 --- a/app/Rules/Fqdn.php +++ b/app/Rules/Fqdn.php @@ -6,11 +6,11 @@ use Illuminate\Support\Arr; use Illuminate\Contracts\Validation\Rule; use Illuminate\Contracts\Validation\DataAwareRule; -class Fqdn implements Rule, DataAwareRule +final class Fqdn implements Rule, DataAwareRule { - protected array $data = []; - protected string $message = ''; - protected ?string $schemeField = null; + private array $data = []; + private string $message = ''; + private ?string $schemeField = null; /** * @param array $data diff --git a/app/Services/Allocations/AssignmentService.php b/app/Services/Allocations/AssignmentService.php index ec79d18f1..11d301322 100644 --- a/app/Services/Allocations/AssignmentService.php +++ b/app/Services/Allocations/AssignmentService.php @@ -40,23 +40,24 @@ class AssignmentService */ public function handle(Node $node, array $data): void { - $explode = explode('/', $data['allocation_ip']); + $allocationIp = $data['allocation_ip']; + $explode = explode('/', $allocationIp); if (count($explode) !== 1) { if (!ctype_digit($explode[1]) || ($explode[1] > self::CIDR_MIN_BITS || $explode[1] < self::CIDR_MAX_BITS)) { throw new CidrOutOfRangeException(); } } + $underlying = 'Unknown IP'; try { // TODO: how should we approach supporting IPv6 with this? // gethostbyname only supports IPv4, but the alternative (dns_get_record) returns // an array of records, which is not ideal for this use case, we need a SINGLE // IP to use, not multiple. - $underlying = gethostbyname($data['allocation_ip']); + $underlying = gethostbyname($allocationIp); $parsed = Network::parse($underlying); } catch (Exception $exception) { - /* @noinspection PhpUndefinedVariableInspection */ - throw new DisplayException("Could not parse provided allocation IP address ({$underlying}): {$exception->getMessage()}", $exception); + throw new DisplayException("Could not parse provided allocation IP address for $allocationIp ($underlying): {$exception->getMessage()}", $exception); } $this->connection->beginTransaction(); diff --git a/app/Services/Backups/DeleteBackupService.php b/app/Services/Backups/DeleteBackupService.php index fd65969c1..bbb54ce6a 100644 --- a/app/Services/Backups/DeleteBackupService.php +++ b/app/Services/Backups/DeleteBackupService.php @@ -73,7 +73,10 @@ class DeleteBackupService /** @var \Pterodactyl\Extensions\Filesystem\S3Filesystem $adapter */ $adapter = $this->manager->adapter(Backup::ADAPTER_AWS_S3); - $adapter->getClient()->deleteObject([ + /** @var \Aws\S3\S3Client $client */ + $client = $adapter->getClient(); + + $client->deleteObject([ 'Bucket' => $adapter->getBucket(), 'Key' => sprintf('%s/%s.tar.gz', $backup->server->uuid, $backup->uuid), ]); diff --git a/app/Services/Backups/InitiateBackupService.php b/app/Services/Backups/InitiateBackupService.php index be8f96632..f14275403 100644 --- a/app/Services/Backups/InitiateBackupService.php +++ b/app/Services/Backups/InitiateBackupService.php @@ -98,17 +98,17 @@ class InitiateBackupService // Get the oldest backup the server has that is not "locked" (indicating a backup that should // never be automatically purged). If we find a backup we will delete it and then continue with // this process. If no backup is found that can be used an exception is thrown. - /** @var \Pterodactyl\Models\Backup $oldest */ $oldest = $successful->where('is_locked', false)->orderBy('created_at')->first(); if (!$oldest) { throw new TooManyBackupsException($server->backup_limit); } + /* @var Backup $oldest */ $this->deleteBackupService->handle($oldest); } return $this->connection->transaction(function () use ($server, $name) { - /** @var \Pterodactyl\Models\Backup $backup */ + /** @var Backup $backup */ $backup = $this->repository->create([ 'server_id' => $server->id, 'uuid' => Uuid::uuid4()->toString(), diff --git a/app/Services/Databases/DatabaseManagementService.php b/app/Services/Databases/DatabaseManagementService.php index b70cb8b4d..0635c1c70 100644 --- a/app/Services/Databases/DatabaseManagementService.php +++ b/app/Services/Databases/DatabaseManagementService.php @@ -119,6 +119,7 @@ class DatabaseManagementService }); } catch (Exception $exception) { try { + /** @var ?Database $database */ if ($database instanceof Database) { $this->repository->dropDatabase($database->database); $this->repository->dropUser($database->username, $database->remote); diff --git a/app/Services/Deployment/FindViableNodesService.php b/app/Services/Deployment/FindViableNodesService.php index a95211c3f..bd2acfdd2 100644 --- a/app/Services/Deployment/FindViableNodesService.php +++ b/app/Services/Deployment/FindViableNodesService.php @@ -78,7 +78,7 @@ class FindViableNodesService ->where('nodes.public', 1); if (!empty($this->locations)) { - $query = $query->whereIn('nodes.location_id', $this->locations); + $query = $query->whereIn('location_id', $this->locations); } $results = $query->groupBy('nodes.id') diff --git a/app/Services/Schedules/ProcessScheduleService.php b/app/Services/Schedules/ProcessScheduleService.php index cfbc7e5ca..d1b5811a8 100644 --- a/app/Services/Schedules/ProcessScheduleService.php +++ b/app/Services/Schedules/ProcessScheduleService.php @@ -27,13 +27,13 @@ class ProcessScheduleService */ public function handle(Schedule $schedule, bool $now = false): void { - /** @var \Pterodactyl\Models\Task $task */ $task = $schedule->tasks()->orderBy('sequence_id')->first(); if (is_null($task)) { throw new DisplayException('Cannot process schedule for task execution: no tasks are registered.'); } + /* @var \Pterodactyl\Models\Task $task */ $this->connection->transaction(function () use ($schedule, $task) { $schedule->forceFill([ 'is_processing' => true, diff --git a/app/Services/Servers/BuildModificationService.php b/app/Services/Servers/BuildModificationService.php index 05553d7f1..b7a22fdaa 100644 --- a/app/Services/Servers/BuildModificationService.php +++ b/app/Services/Servers/BuildModificationService.php @@ -88,14 +88,13 @@ class BuildModificationService // Handle the addition of allocations to this server. Only assign allocations that are not currently // assigned to a different server, and only allocations on the same node as the server. if (!empty($data['add_allocations'])) { - $query = Allocation::query() - ->where('node_id', $server->node_id) + $query = $server->node->allocations() ->whereIn('id', $data['add_allocations']) ->whereNull('server_id'); // Keep track of all the allocations we're just now adding so that we can use the first // one to reset the default allocation to. - $freshlyAllocated = $query->pluck('id')->first(); + $freshlyAllocated = $query->first()->id ?? null; $query->update(['server_id' => $server->id, 'notes' => null]); } diff --git a/app/Services/Servers/ServerCreationService.php b/app/Services/Servers/ServerCreationService.php index 2c9b4cf84..62e848aa0 100644 --- a/app/Services/Servers/ServerCreationService.php +++ b/app/Services/Servers/ServerCreationService.php @@ -82,7 +82,7 @@ class ServerCreationService // // If that connection fails out we will attempt to perform a cleanup by just // deleting the server itself from the system. - /** @var \Pterodactyl\Models\Server $server */ + /** @var Server $server */ $server = $this->connection->transaction(function () use ($data, $eggVariableData) { // Create the server and assign any additional allocations to it. $server = $this->createModel($data); @@ -115,7 +115,7 @@ class ServerCreationService */ private function configureDeployment(array $data, DeploymentObject $deployment): Allocation { - /** @var \Illuminate\Support\Collection $nodes */ + /** @var Collection $nodes */ $nodes = $this->findViableNodesService->setLocations($deployment->getLocations()) ->setDisk(Arr::get($data, 'disk')) ->setMemory(Arr::get($data, 'memory')) @@ -136,7 +136,7 @@ class ServerCreationService { $uuid = $this->generateUniqueUuidCombo(); - /** @var \Pterodactyl\Models\Server $model */ + /** @var Server $model */ $model = $this->repository->create([ 'external_id' => Arr::get($data, 'external_id'), 'uuid' => $uuid, diff --git a/app/Services/Users/UserDeletionService.php b/app/Services/Users/UserDeletionService.php index f7f060cee..0f373240f 100644 --- a/app/Services/Users/UserDeletionService.php +++ b/app/Services/Users/UserDeletionService.php @@ -25,7 +25,7 @@ class UserDeletionService * * @throws \Pterodactyl\Exceptions\DisplayException */ - public function handle(int|User $user): ?bool + public function handle(int|User $user): void { if ($user instanceof User) { $user = $user->id; @@ -36,6 +36,6 @@ class UserDeletionService throw new DisplayException($this->translator->get('admin/user.exceptions.user_has_servers')); } - return $this->repository->delete($user); + $this->repository->delete($user); } } diff --git a/app/Transformers/Api/Application/ServerVariableTransformer.php b/app/Transformers/Api/Application/ServerVariableTransformer.php index 25e8f879b..e27d1e013 100644 --- a/app/Transformers/Api/Application/ServerVariableTransformer.php +++ b/app/Transformers/Api/Application/ServerVariableTransformer.php @@ -4,6 +4,7 @@ namespace Pterodactyl\Transformers\Api\Application; use League\Fractal\Resource\Item; use Pterodactyl\Models\EggVariable; +use Pterodactyl\Models\ServerVariable; use League\Fractal\Resource\NullResource; use Pterodactyl\Services\Acl\Api\AdminAcl; diff --git a/composer.json b/composer.json index 160537b6b..a03a9dcfc 100644 --- a/composer.json +++ b/composer.json @@ -61,6 +61,7 @@ "laravel/sail": "~1.16", "mockery/mockery": "~1.5", "nunomaduro/collision": "~6.3", + "nunomaduro/larastan": "^2.0", "php-mock/php-mock-phpunit": "~2.6", "phpunit/phpunit": "~9.5", "spatie/laravel-ignition": "~1.5" diff --git a/composer.lock b/composer.lock index 9f4b73f6f..381b321ae 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ae61e7d6e405e3a59c8a54f3eefa2c50", + "content-hash": "88999658a97429a6840f4da57ea115b1", "packages": [ { "name": "aws/aws-crt-php", @@ -9004,6 +9004,103 @@ ], "time": "2022-09-29T12:29:49+00:00" }, + { + "name": "nunomaduro/larastan", + "version": "2.2.7", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/larastan.git", + "reference": "a3f67a4a668e477751557b0b19ad2c870e1e4e56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/larastan/zipball/a3f67a4a668e477751557b0b19ad2c870e1e4e56", + "reference": "a3f67a4a668e477751557b0b19ad2c870e1e4e56", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^9", + "illuminate/container": "^9", + "illuminate/contracts": "^9", + "illuminate/database": "^9", + "illuminate/http": "^9", + "illuminate/pipeline": "^9", + "illuminate/support": "^9", + "mockery/mockery": "^1.4.4", + "php": "^8.0.2", + "phpmyadmin/sql-parser": "^5.5", + "phpstan/phpstan": "^1.8.7" + }, + "require-dev": { + "nikic/php-parser": "^4.13.2", + "orchestra/testbench": "^7.0.0", + "phpunit/phpunit": "^9.5.11" + }, + "suggest": { + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "NunoMaduro\\Larastan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel", + "keywords": [ + "PHPStan", + "code analyse", + "code analysis", + "larastan", + "laravel", + "package", + "php", + "static analysis" + ], + "support": { + "issues": "https://github.com/nunomaduro/larastan/issues", + "source": "https://github.com/nunomaduro/larastan/tree/2.2.7" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/canvural", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-10-30T15:02:40+00:00" + }, { "name": "phar-io/manifest", "version": "2.0.3", @@ -9422,6 +9519,138 @@ }, "time": "2022-10-14T12:47:21+00:00" }, + { + "name": "phpmyadmin/sql-parser", + "version": "5.5.0", + "source": { + "type": "git", + "url": "https://github.com/phpmyadmin/sql-parser.git", + "reference": "8ab99cd0007d880f49f5aa1807033dbfa21b1cb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/8ab99cd0007d880f49f5aa1807033dbfa21b1cb5", + "reference": "8ab99cd0007d880f49f5aa1807033dbfa21b1cb5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "symfony/polyfill-mbstring": "^1.3" + }, + "conflict": { + "phpmyadmin/motranslator": "<3.0" + }, + "require-dev": { + "phpmyadmin/coding-standard": "^3.0", + "phpmyadmin/motranslator": "^4.0 || ^5.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.2", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/php-code-coverage": "*", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.16.1", + "vimeo/psalm": "^4.11", + "zumba/json-serializer": "^3.0" + }, + "suggest": { + "ext-mbstring": "For best performance", + "phpmyadmin/motranslator": "Translate messages to your favorite locale" + }, + "bin": [ + "bin/highlight-query", + "bin/lint-query", + "bin/tokenize-query" + ], + "type": "library", + "autoload": { + "psr-4": { + "PhpMyAdmin\\SqlParser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "The phpMyAdmin Team", + "email": "developers@phpmyadmin.net", + "homepage": "https://www.phpmyadmin.net/team/" + } + ], + "description": "A validating SQL lexer and parser with a focus on MySQL dialect.", + "homepage": "https://github.com/phpmyadmin/sql-parser", + "keywords": [ + "analysis", + "lexer", + "parser", + "sql" + ], + "support": { + "issues": "https://github.com/phpmyadmin/sql-parser/issues", + "source": "https://github.com/phpmyadmin/sql-parser" + }, + "time": "2021-12-09T04:31:52+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.8.11", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "46e223dd68a620da18855c23046ddb00940b4014" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/46e223dd68a620da18855c23046ddb00940b4014", + "reference": "46e223dd68a620da18855c23046ddb00940b4014", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.8.11" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-10-24T15:45:13+00:00" + }, { "name": "phpunit/php-code-coverage", "version": "9.2.17", diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 000000000..e12e72eb5 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,35 @@ +includes: + - ./vendor/nunomaduro/larastan/extension.neon + +parameters: + + paths: + - app/ + + # Level 9 is the highest level + level: 4 + + ignoreErrors: + # Ignore dynamic methods from 3rd Party Vendor + - '#Call to an undefined method Prologue\\Alerts\\AlertsMessageBag::(success|info|warning|danger)\(\)#' + + # Ignore repository interface missing methods + - '#Call to an undefined method Pterodactyl\\Repositories\\Wings\\DaemonRepository::(\w+)\(\)#' + + # Ignore magic spatie calls + - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Builder::allowed(\w+)\(\)#' + + # This should be replaced with resources instead of a magic transformer factory, robots in disguise + - '#Method Pterodactyl\\Http\\Controllers\\Api\\Client\\ClientApiController::getTransformer\(\) should return T#' + + excludePaths: + - app/Repositories + + # Bug in Laravel Framework #44807 + - app/Console/Commands/Overrides/UpCommand.php + + # More magic spatie to be replaced + - app/Extensions/Spatie/Fractalistic/Fractal.php + +# +# checkMissingIterableValueType: false