diff --git a/app/Http/Controllers/Api/Application/VersionController.php b/app/Http/Controllers/Api/Application/VersionController.php new file mode 100644 index 000000000..6956226b3 --- /dev/null +++ b/app/Http/Controllers/Api/Application/VersionController.php @@ -0,0 +1,34 @@ +softwareVersionService = $softwareVersionService; + } + + /** + * ? + */ + public function __invoke() + { + return new JsonResponse($this->softwareVersionService->getVersionData()); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 929de15fc..f34237819 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,15 +2,12 @@ namespace Pterodactyl\Providers; -use View; -use Cache; use Pterodactyl\Models\User; use Pterodactyl\Models\Server; use Pterodactyl\Models\Subuser; use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; use Pterodactyl\Observers\UserObserver; -use Pterodactyl\Extensions\Themes\Theme; use Pterodactyl\Observers\ServerObserver; use Pterodactyl\Observers\SubuserObserver; @@ -26,9 +23,6 @@ class AppServiceProvider extends ServiceProvider User::observe(UserObserver::class); Server::observe(ServerObserver::class); Subuser::observe(SubuserObserver::class); - - View::share('appVersion', $this->versionData()['version'] ?? 'undefined'); - View::share('appIsGit', $this->versionData()['is_git'] ?? false); } /** @@ -41,39 +35,5 @@ class AppServiceProvider extends ServiceProvider if (! config('pterodactyl.load_environment_only', false) && $this->app->environment() !== 'testing') { $this->app->register(SettingsServiceProvider::class); } - - $this->app->singleton('extensions.themes', function () { - return new Theme; - }); - } - - /** - * Return version information for the footer. - * - * @return array - */ - protected function versionData() - { - return Cache::remember('git-version', 5, function () { - if (file_exists(base_path('.git/HEAD'))) { - $head = explode(' ', file_get_contents(base_path('.git/HEAD'))); - - if (array_key_exists(1, $head)) { - $path = base_path('.git/' . trim($head[1])); - } - } - - if (isset($path) && file_exists($path)) { - return [ - 'version' => substr(file_get_contents($path), 0, 8), - 'is_git' => true, - ]; - } - - return [ - 'version' => config('app.version'), - 'is_git' => false, - ]; - }); } } diff --git a/app/Services/Helpers/SoftwareVersionService.php b/app/Services/Helpers/SoftwareVersionService.php index 893c097d0..72daa2282 100644 --- a/app/Services/Helpers/SoftwareVersionService.php +++ b/app/Services/Helpers/SoftwareVersionService.php @@ -6,6 +6,7 @@ use Exception; use GuzzleHttp\Client; use Carbon\CarbonImmutable; use Illuminate\Support\Arr; +use Illuminate\Support\Str; use Illuminate\Contracts\Cache\Repository as CacheRepository; use Pterodactyl\Exceptions\Service\Helper\CdnVersionFetchingException; @@ -16,17 +17,17 @@ class SoftwareVersionService /** * @var array */ - private static $result; + private static array $result; /** * @var \Illuminate\Contracts\Cache\Repository */ - protected $cache; + protected CacheRepository $cache; /** * @var \GuzzleHttp\Client */ - protected $client; + protected Client $client; /** * SoftwareVersionService constructor. @@ -44,46 +45,36 @@ class SoftwareVersionService self::$result = $this->cacheVersionData(); } + /** + * Gets the current version of the panel that is being used. + * + * @return string + */ + public function getVersion(): string + { + return config()->get('app.version'); + } + /** * Get the latest version of the panel from the CDN servers. * * @return string */ - public function getPanel() + public function getLatestPanel(): string { return Arr::get(self::$result, 'panel') ?? 'error'; } /** - * Get the latest version of the daemon from the CDN servers. + * Get the latest version of wings from the CDN servers. * * @return string */ - public function getDaemon() + public function getLatestWings(): string { return Arr::get(self::$result, 'wings') ?? 'error'; } - /** - * Get the URL to the discord server. - * - * @return string - */ - public function getDiscord() - { - return Arr::get(self::$result, 'discord') ?? 'https://pterodactyl.io/discord'; - } - - /** - * Get the URL for donations. - * - * @return string - */ - public function getDonations() - { - return Arr::get(self::$result, 'donations') ?? 'https://paypal.me/PterodactylSoftware'; - } - /** * Determine if the current version of the panel is the latest. * @@ -91,26 +82,29 @@ class SoftwareVersionService */ public function isLatestPanel() { - if (config()->get('app.version') === 'canary') { + $version = $this->getVersion(); + if ($version === 'canary') { return true; } - return version_compare(config()->get('app.version'), $this->getPanel()) >= 0; + return version_compare($version, $this->getLatestPanel()) >= 0; } /** - * Determine if a passed daemon version string is the latest. + * Determine if a passed wings version is the latest. * * @param string $version + * * @return bool */ - public function isLatestDaemon($version) + public function isLatestWings(string $version) { - if ($version === '0.0.0-canary') { + // If the version is 'canary' or starts with 'dev-', mark it as the latest. + if ($version === 'canary' || Str::startsWith($version, 'dev-')) { return true; } - return version_compare($version, $this->getDaemon()) >= 0; + return version_compare($version, $this->getLatestWings()) >= 0; } /** @@ -124,14 +118,74 @@ class SoftwareVersionService try { $response = $this->client->request('GET', config()->get('pterodactyl.cdn.url')); - if ($response->getStatusCode() === 200) { - return json_decode($response->getBody(), true); + if ($response->getStatusCode() !== 200) { + throw new CdnVersionFetchingException; } - throw new CdnVersionFetchingException; + return json_decode($response->getBody(), true); } catch (Exception $exception) { return []; } }); } + + /** + * Return version information for the footer. + * + * @return array + */ + protected function versionData(): array + { + return $this->cache->remember('git-version', 5, function () { + $configVersion = config()->get('app.version'); + + if (file_exists(base_path('.git/HEAD'))) { + $head = explode(' ', file_get_contents(base_path('.git/HEAD'))); + + if (array_key_exists(1, $head)) { + $path = base_path('.git/' . trim($head[1])); + } + } + + if (isset($path) && file_exists($path)) { + return [ + 'version' => substr(file_get_contents($path), 0, 8), + 'is_git' => true, + ]; + } + + return [ + 'version' => $configVersion, + 'is_git' => false, + ]; + }); + } + + /** + * ? + * + * @return array + */ + public function getVersionData(): array + { + $versionData = $this->versionData(); + if ($versionData['is_git']) { + $git = $versionData['version']; + } else { + $git = null; + } + + return [ + 'panel' => [ + 'current' => $this->getVersion(), + 'latest' => $this->getLatestPanel(), + ], + + 'wings' => [ + 'latest' => $this->getLatestWings(), + ], + + 'git' => $git, + ]; + } } diff --git a/resources/scripts/api/admin/getVersion.ts b/resources/scripts/api/admin/getVersion.ts new file mode 100644 index 000000000..bed670b4c --- /dev/null +++ b/resources/scripts/api/admin/getVersion.ts @@ -0,0 +1,22 @@ +import http from '@/api/http'; + +export interface VersionData { + panel: { + current: string; + latest: string; + }; + + wings: { + latest: string; + }; + + git: string | null; +} + +export default (): Promise => { + return new Promise((resolve, reject) => { + http.get('/api/application/version') + .then(({ data }) => resolve(data)) + .catch(reject); + }); +}; diff --git a/routes/api-application.php b/routes/api-application.php index f62aa1775..ecaa5d729 100644 --- a/routes/api-application.php +++ b/routes/api-application.php @@ -2,6 +2,8 @@ use Illuminate\Support\Facades\Route; +Route::get('/version', 'VersionController'); + /* |-------------------------------------------------------------------------- | Database Controller Routes