Skip to content

Commit

Permalink
feat: Merge pull request #5 from jameskitt616/fix-panel-installer
Browse files Browse the repository at this point in the history
Update Panel Installer
add redis configuration
add timezone configuration
fix and clean code
  • Loading branch information
S0ly committed Jun 13, 2024
2 parents 392b601 + effc8ac commit bb21c21
Show file tree
Hide file tree
Showing 4 changed files with 522 additions and 339 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
"require": {
"php": "^8.1",
"ext-intl": "*",
"ext-mysqli": "*",
"ext-curl": "*",
"biscolab/laravel-recaptcha": "^5.4",
"doctrine/dbal": "^3.5.3",
"guzzlehttp/guzzle": "^7.5",
Expand Down
225 changes: 148 additions & 77 deletions public/install/forms.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,24 @@

use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
use Predis\Client;

require 'phpmailer/Exception.php';
require 'phpmailer/PHPMailer.php';
require 'phpmailer/SMTP.php';

include 'functions.php';

if (isset($_POST['timezoneConfig'])) {
wh_log('Setting up Timezone', 'debug');
$timezone = $_POST['timezone'];

setenv('APP_TIMEZONE', $timezone);

wh_log('Timezone set: ' . $timezone, 'debug');
header('LOCATION: index.php?step=3');
}

mysqli_report(MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ALL);

if (isset($_POST['checkDB'])) {
Expand All @@ -31,7 +42,7 @@
$db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
} catch (mysqli_sql_exception $e) {
wh_log($e->getMessage(), 'error');
header('LOCATION: index.php?step=2&message=' . $e->getMessage());
header('LOCATION: index.php?step=3&message=' . $e->getMessage());
exit();
}

Expand All @@ -45,23 +56,7 @@
}

wh_log('Database connection successful', 'debug');
header('LOCATION: index.php?step=2.5');
}

if (isset($_POST['checkGeneral'])) {
wh_log('setting app settings', 'debug');
$appname = '"' . $_POST['name'] . '"';
$appurl = $_POST['url'];

if (substr($appurl, -1) === '/') {
$appurl = substr_replace($appurl, '', -1);
}

setenv('APP_NAME', $appname);
setenv('APP_URL', $appurl);

wh_log('App settings set', 'debug');
header('LOCATION: index.php?step=4');
header('LOCATION: index.php?step=3.5');
}

if (isset($_POST['feedDB'])) {
Expand All @@ -84,13 +79,68 @@
wh_log($logs, 'debug');

wh_log('Feeding the Database successful', 'debug');
header('LOCATION: index.php?step=3');
} catch (\Throwable $th) {
header('LOCATION: index.php?step=4');
} catch (Throwable $th) {
wh_log('Feeding the Database failed', 'error');
header("LOCATION: index.php?step=2.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
header("LOCATION: index.php?step=3.5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs !");
}
}

if (isset($_POST['redisSetup'])) {
wh_log('Setting up Redis', 'debug');
$redisHost = $_POST['redishost'];
$redisPort = $_POST['redisport'];
$redisPassword = $_POST['redispassword'];

$redisClient = new Client([
'host' => $redisHost,
'port' => $redisPort,
'password' => $redisPassword,
'timeout' => 1.0,
]);

try {
$redisClient->ping();

setenv('MEMCACHED_HOST', $redisHost);
setenv('REDIS_HOST', $redisHost);
setenv('REDIS_PORT', $redisPort);
setenv('REDIS_PASSWORD', ($redisPassword === '' ? 'null' : $redisPassword));

wh_log('Redis connection successful. Settings updated.', 'debug');
header('LOCATION: index.php?step=5');
} catch (Throwable $th) {
wh_log('Redis connection failed. Settings updated.', 'debug');
header("LOCATION: index.php?step=4&message=Please check your credentials!<br>" . $th->getMessage());
}
}

if (isset($_POST['checkGeneral'])) {
wh_log('setting app settings', 'debug');
$appname = '"' . $_POST['name'] . '"';
$appurl = $_POST['url'];

$parsedUrl = parse_url($appurl);

if (!isset($parsedUrl['scheme'])) {
header('LOCATION: index.php?step=5&message=Please set an URL Scheme like "https://"!');
exit();
}

if (!isset($parsedUrl['host'])) {
header('LOCATION: index.php?step=5&message=Please set an valid URL host like "https://ctrlpanel.example.com"!');
exit();
}

$appurl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];

setenv('APP_NAME', $appname);
setenv('APP_URL', $appurl);

wh_log('App settings set', 'debug');
header('LOCATION: index.php?step=6');
}

if (isset($_POST['checkSMTP'])) {
wh_log('Checking SMTP Settings', 'debug');
try {
Expand Down Expand Up @@ -120,7 +170,7 @@
$mail->send();
} catch (Exception $e) {
wh_log($mail->ErrorInfo, 'error');
header('LOCATION: index.php?step=4&message=Something went wrong while sending test E-Mail!<br>' . $mail->ErrorInfo);
header('LOCATION: index.php?step=6&message=Something went wrong while sending test E-Mail!<br>' . $mail->ErrorInfo);
exit();
}

Expand All @@ -129,7 +179,7 @@
$db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
if ($db->connect_error) {
wh_log($db->connect_error, 'error');
header('LOCATION: index.php?step=4&message=Could not connect to the Database: ');
header('LOCATION: index.php?step=6&message=Could not connect to the Database: ');
exit();
}
$values = [
Expand All @@ -147,7 +197,7 @@
}

wh_log('Database updated', 'debug');
header('LOCATION: index.php?step=5');
header('LOCATION: index.php?step=7');
}

if (isset($_POST['checkPtero'])) {
Expand All @@ -157,10 +207,20 @@
$key = $_POST['key'];
$clientkey = $_POST['clientkey'];

if (substr($url, -1) === '/') {
$url = substr_replace($url, '', -1);
$parsedUrl = parse_url($url);

if (!isset($parsedUrl['scheme'])) {
header('LOCATION: index.php?step=7&message=Please set an URL Scheme like "https://"!');
exit();
}

if (!isset($parsedUrl['host'])) {
header('LOCATION: index.php?step=7&message=Please set an valid URL host like "https://panel.example.com"!');
exit();
}

$url = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];

$callpteroURL = $url . '/api/client/account';
$call = curl_init();

Expand All @@ -173,7 +233,7 @@
]);
$callresponse = curl_exec($call);
$callresult = json_decode($callresponse, true);
curl_close($call); // Close the connection
curl_close($call);

$pteroURL = $url . '/api/application/users';
$ch = curl_init();
Expand All @@ -187,38 +247,46 @@
]);
$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch); // Close the connection
curl_close($ch);

if (!is_array($result) and $result['errors'][0] !== null) {
header('LOCATION: index.php?step=5&message=Couldn\'t connect to Pterodactyl. Make sure your API key has all read and write permissions!');
if (!is_array($result)) {
wh_log('No array in response found', 'error');
header('LOCATION: index.php?step=7&message=An unknown Error occured, please try again!');
}

if (array_key_exists('errors', $result) && $result['errors'][0]['detail'] === 'This action is unauthorized.') {
wh_log('API CALL ERROR: ' . $result['errors'][0]['code'], 'error');
header('LOCATION: index.php?step=7&message=Couldn\'t connect to Pterodactyl. Make sure your Application API key has all read and write permissions!');
exit();
} elseif (!is_array($callresult) and $callresult['errors'][0] !== null or $callresult['attributes']['admin'] == false) {
header('LOCATION: index.php?step=5&message=Your ClientAPI Key is wrong or the account is not an admin!');
}

if (array_key_exists('errors', $callresult) && $callresult['errors'][0]['detail'] === 'Unauthenticated.') {
wh_log('API CALL ERROR: ' . $callresult['errors'][0]['code'], 'error');
header('LOCATION: index.php?step=7&message=Your ClientAPI Key is wrong or the account is not an admin!');
exit();
}

try {
run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'");
run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
wh_log('Database updated', 'debug');
header('LOCATION: index.php?step=8');
} catch (Throwable $th) {
wh_log("Setting Pterodactyl information failed.", 'error');
header("LOCATION: index.php?step=7&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
exit();
} else {
wh_log('Pterodactyl Settings are correct', 'debug');

try {
run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'");
run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'");
run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'");
wh_log('Database updated', 'debug');
header('LOCATION: index.php?step=6');
} catch (\Throwable $th) {
wh_log("Setting Pterodactyl information failed.", 'error');
header("LOCATION: index.php?step=5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
}
}
}

if (isset($_POST['createUser'])) {
wh_log('Getting Pterodactyl User', 'debug');
$db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
if ($db->connect_error) {
wh_log($db->connect_error, 'error');
header('LOCATION: index.php?step=6&message=Could not connect to the Database');

try {
$db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
} catch (Throwable $th) {
wh_log($th->getMessage(), 'error');
header('LOCATION: index.php?step=8&message=Could not connect to the Database');
exit();
}

Expand All @@ -227,36 +295,36 @@
$repass = $_POST['repass'];

try {
$panel_url = run_console("php artisan settings:get 'PterodactylSettings' 'panel_url' --sameline");
$admin_token = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
wh_log('Database updated', 'debug');
header('LOCATION: index.php?step=6');
} catch (\Throwable $th) {
$panelUrl = run_console("php artisan settings:get 'PterodactylSettings' 'panel_url' --sameline");
$adminToken = run_console("php artisan settings:get 'PterodactylSettings' 'admin_token' --sameline");
} catch (Throwable $th) {
wh_log("Getting Pterodactyl information failed.", 'error');
header("LOCATION: index.php?step=5&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
header("LOCATION: index.php?step=7&message=" . $th->getMessage() . " <br>Please check the installer.log file in /var/www/controlpanel/storage/logs!");
exit();
}

$panel_api_url = $panel_url . '/api/application/users/' . $pteroID;
$panelApiUrl = $panelUrl . '/api/application/users/' . $pteroID;

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $panel_api_url);
curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'Content-Type: application/json',
'Authorization: Bearer ' . $admin_token,
'Authorization: Bearer ' . $adminToken,
]);
$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch); // Close the connection
curl_close($ch);

if (!$result['attributes']['email']) {
header('LOCATION: index.php?step=6&message=Could not find the user with pterodactyl ID ' . $pteroID);
if ($pass !== $repass) {
header('LOCATION: index.php?step=8&message=The Passwords did not match!');
exit();
}
if ($pass !== $repass) {
header('LOCATION: index.php?step=6&message=The Passwords did not match!');

if (array_key_exists('errors', $result)) {
header('LOCATION: index.php?step=8&message=Could not find the user with pterodactyl ID ' . $pteroID);
exit();
}

Expand All @@ -266,12 +334,12 @@

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $panel_api_url);
curl_setopt($ch, CURLOPT_URL, $panelApiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'Content-Type: application/json',
'Authorization: Bearer ' . $admin_token,
'Authorization: Bearer ' . $adminToken,
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'email' => $mail,
Expand All @@ -282,22 +350,25 @@
]);
$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch); // Close the connection

if (!is_array($result) or in_array($result['errors'][0]['code'], $result)) {
header('LOCATION: index.php?step=5&message=Couldn\'t connect to Pterodactyl. Make sure your API key has all read and write permissions!');
exit();
}
curl_close($ch);

$random = generateRandomString();

$query1 = 'INSERT INTO `' . getenv('DB_DATABASE') . "`.`users` (`name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`, `referral_code`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP, '$random')";
$query2 = "INSERT INTO `" . getenv('DB_DATABASE') . "`.`model_has_roles` (`role_id`, `model_type`, `model_id`) VALUES ('1', 'App\\\Models\\\User', '1')";
if ($db->query($query1) && $db->query($query2)) {
wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID, 'info');
header('LOCATION: index.php?step=7');
} else {
wh_log($db->error, 'error');
header('LOCATION: index.php?step=6&message=Something went wrong when communicating with the Database');
try {
$db->query($query1);
$db->query($query2);

wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID);
header('LOCATION: index.php?step=9');
} catch (Throwable $th) {
wh_log($th->getMessage(), 'error');
if (str_contains($th->getMessage(), 'Duplicate entry')) {
header('LOCATION: index.php?step=8&message=User already exists in CtrlPanel\'s Database.');
} else {
header('LOCATION: index.php?step=8&message=Something went wrong when communicating with the Database.');
}
exit();
}
}
5 changes: 5 additions & 0 deletions public/install/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,8 @@ function generateRandomString(int $length = 8): string

return $randomString;
}

function determineIfRunningInDocker(): bool
{
return file_exists('/.dockerenv');
}
Loading

0 comments on commit bb21c21

Please sign in to comment.