فهرست منبع

Merge branch 'development' of https://github.com/1day2die/dashboard into development

1day2die 2 سال پیش
والد
کامیت
9ddb44c3dc

+ 20 - 21
app/Classes/PterodactylClient.php

@@ -24,19 +24,18 @@ class PterodactylClient
 
 
     public PendingRequest $client;
     public PendingRequest $client;
 
 
-    public PendingRequest $client_admin;
-    
+    public PendingRequest $application;
+
     public function __construct(PterodactylSettings $ptero_settings)
     public function __construct(PterodactylSettings $ptero_settings)
     {
     {
         $server_settings = new ServerSettings();
         $server_settings = new ServerSettings();
-        
+
         try {
         try {
             $this->client = $this->client($ptero_settings);
             $this->client = $this->client($ptero_settings);
-            $this->client_admin = $this->clientAdmin($ptero_settings);
+            $this->application = $this->clientAdmin($ptero_settings);
             $this->per_page_limit = $ptero_settings->per_page_limit;
             $this->per_page_limit = $ptero_settings->per_page_limit;
             $this->allocation_limit = $server_settings->allocation_limit;
             $this->allocation_limit = $server_settings->allocation_limit;
-        }
-        catch (Exception $exception) {
+        } catch (Exception $exception) {
             logger('Failed to construct Pterodactyl client, Settings table not available?', ['exception' => $exception]);
             logger('Failed to construct Pterodactyl client, Settings table not available?', ['exception' => $exception]);
         }
         }
     }
     }
@@ -94,7 +93,7 @@ class PterodactylClient
     public function getEggs(Nest $nest)
     public function getEggs(Nest $nest)
     {
     {
         try {
         try {
-            $response = $this->client_admin->get("application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . $this->per_page_limit);
+            $response = $this->application->get("application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . $this->per_page_limit);
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -113,7 +112,7 @@ class PterodactylClient
     public function getNodes()
     public function getNodes()
     {
     {
         try {
         try {
-            $response = $this->client_admin->get('application/nodes?per_page=' . $this->per_page_limit);
+            $response = $this->application->get('application/nodes?per_page=' . $this->per_page_limit);
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -133,7 +132,7 @@ class PterodactylClient
     public function getNode($id)
     public function getNode($id)
     {
     {
         try {
         try {
-            $response = $this->client_admin->get('application/nodes/' . $id);
+            $response = $this->application->get('application/nodes/' . $id);
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -147,7 +146,7 @@ class PterodactylClient
     public function getServers()
     public function getServers()
     {
     {
         try {
         try {
-            $response = $this->client_admin->get('application/servers?per_page=' . $this->per_page_limit);
+            $response = $this->application->get('application/servers?per_page=' . $this->per_page_limit);
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -166,7 +165,7 @@ class PterodactylClient
     public function getNests()
     public function getNests()
     {
     {
         try {
         try {
-            $response = $this->client_admin->get('application/nests?per_page=' . $this->per_page_limit);
+            $response = $this->application->get('application/nests?per_page=' . $this->per_page_limit);
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -185,7 +184,7 @@ class PterodactylClient
     public function getLocations()
     public function getLocations()
     {
     {
         try {
         try {
-            $response = $this->client_admin->get('application/locations?per_page=' . $this->per_page_limit);
+            $response = $this->application->get('application/locations?per_page=' . $this->per_page_limit);
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -240,7 +239,7 @@ class PterodactylClient
     public function getAllocations(Node $node)
     public function getAllocations(Node $node)
     {
     {
         try {
         try {
-            $response = $this->client_admin->get("application/nodes/{$node->id}/allocations?per_page={$this->allocation_limit}");
+            $response = $this->application->get("application/nodes/{$node->id}/allocations?per_page={$this->allocation_limit}");
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -259,7 +258,7 @@ class PterodactylClient
      */
      */
     public function createServer(Server $server, Egg $egg, int $allocationId)
     public function createServer(Server $server, Egg $egg, int $allocationId)
     {
     {
-        return $this->client_admin->post('application/servers', [
+        return $this->application->post('application/servers', [
             'name' => $server->name,
             'name' => $server->name,
             'external_id' => $server->id,
             'external_id' => $server->id,
             'user' => $server->user->pterodactyl_id,
             'user' => $server->user->pterodactyl_id,
@@ -288,7 +287,7 @@ class PterodactylClient
     public function suspendServer(Server $server)
     public function suspendServer(Server $server)
     {
     {
         try {
         try {
-            $response = $this->client_admin->post("application/servers/$server->pterodactyl_id/suspend");
+            $response = $this->application->post("application/servers/$server->pterodactyl_id/suspend");
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -302,7 +301,7 @@ class PterodactylClient
     public function unSuspendServer(Server $server)
     public function unSuspendServer(Server $server)
     {
     {
         try {
         try {
-            $response = $this->client_admin->post("application/servers/$server->pterodactyl_id/unsuspend");
+            $response = $this->application->post("application/servers/$server->pterodactyl_id/unsuspend");
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -322,7 +321,7 @@ class PterodactylClient
     public function getUser(int $pterodactylId)
     public function getUser(int $pterodactylId)
     {
     {
         try {
         try {
-            $response = $this->client_admin->get("application/users/{$pterodactylId}");
+            $response = $this->application->get("application/users/{$pterodactylId}");
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -342,7 +341,7 @@ class PterodactylClient
     public function getServerAttributes(int $pterodactylId, bool $deleteOn404 = false)
     public function getServerAttributes(int $pterodactylId, bool $deleteOn404 = false)
     {
     {
         try {
         try {
-            $response = $this->client_admin->get("application/servers/{$pterodactylId}?include=egg,node,nest,location");
+            $response = $this->application->get("application/servers/{$pterodactylId}?include=egg,node,nest,location");
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }
@@ -371,7 +370,7 @@ class PterodactylClient
      */
      */
     public function updateServer(Server $server, Product $product)
     public function updateServer(Server $server, Product $product)
     {
     {
-        return $this->client_admin->patch("application/servers/{$server->pterodactyl_id}/build", [
+        return $this->application->patch("application/servers/{$server->pterodactyl_id}/build", [
             'allocation' => $server->allocation,
             'allocation' => $server->allocation,
             'memory' => $product->memory,
             'memory' => $product->memory,
             'swap' => $product->swap,
             'swap' => $product->swap,
@@ -396,7 +395,7 @@ class PterodactylClient
      */
      */
     public function updateServerOwner(Server $server, int $userId)
     public function updateServerOwner(Server $server, int $userId)
     {
     {
-        return $this->client_admin->patch("application/servers/{$server->pterodactyl_id}/details", [
+        return $this->application->patch("application/servers/{$server->pterodactyl_id}/details", [
             'name' => $server->name,
             'name' => $server->name,
             'user' => $userId,
             'user' => $userId,
         ]);
         ]);
@@ -435,7 +434,7 @@ class PterodactylClient
     public function checkNodeResources(Node $node, int $requireMemory, int $requireDisk)
     public function checkNodeResources(Node $node, int $requireMemory, int $requireDisk)
     {
     {
         try {
         try {
-            $response = $this->client_admin->get("application/nodes/{$node->id}");
+            $response = $this->application->get("application/nodes/{$node->id}");
         } catch (Exception $e) {
         } catch (Exception $e) {
             throw self::getException($e->getMessage());
             throw self::getException($e->getMessage());
         }
         }

+ 11 - 19
app/Http/Controllers/Admin/SettingsController.php

@@ -109,26 +109,18 @@ class SettingsController extends Controller
         $settingsClass = new $settings_class();
         $settingsClass = new $settings_class();
 
 
         foreach ($settingsClass->toArray() as $key => $value) {
         foreach ($settingsClass->toArray() as $key => $value) {
-            switch (gettype($request->input($key))) {
-                case 'boolean':
-                    $settingsClass->$key = $request->has($key);
-                    break;
-                case 'string':
-                    $settingsClass->$key = $request->input($key) ?? '';
-                    break;
-                case 'integer':
-                    $settingsClass->$key = $request->input($key) ?? 0;
-                    break;
-                case 'array':
-                    $settingsClass->$key = $request->input($key) ?? [];
-                    break;
-                case 'double':
-                    $settingsClass->$key = $request->input($key) ?? 0.0;
-                    break;
-                case 'NULL':
-                    $settingsClass->$key = null;
-                    break;
+            // Get the type of the settingsclass property
+            $rp = new \ReflectionProperty($settingsClass, $key);
+            $rpType = $rp->getType();
+
+            if ($rpType == 'bool') {
+                $settingsClass->$key = $request->has($key);
+                continue;
             }
             }
+
+            $nullable = $rpType->allowsNull();
+            if ($nullable) $settingsClass->$key = $request->input($key) ?? null;
+            else $settingsClass->$key = $request->input($key);
         }
         }
 
 
         $settingsClass->save();
         $settingsClass->save();

+ 6 - 3
app/Http/Controllers/Admin/UserController.php

@@ -35,7 +35,7 @@ class UserController extends Controller
     {
     {
         $this->pterodactyl = new PterodactylClient($ptero_settings);
         $this->pterodactyl = new PterodactylClient($ptero_settings);
     }
     }
-    
+
     /**
     /**
      * Display a listing of the resource.
      * Display a listing of the resource.
      *
      *
@@ -166,6 +166,10 @@ class UserController extends Controller
      */
      */
     public function destroy(User $user)
     public function destroy(User $user)
     {
     {
+        if ($user->role === 'admin' && User::query()->where('role', 'admin')->count() === 1) {
+            return redirect()->back()->with('error', __('You can not delete the last admin!'));
+        }
+
         $user->delete();
         $user->delete();
 
 
         return redirect()->back()->with('success', __('user has been removed!'));
         return redirect()->back()->with('success', __('user has been removed!'));
@@ -258,8 +262,7 @@ class UserController extends Controller
         $users = $all ? User::all() : User::whereIn('id', $data['users'])->get();
         $users = $all ? User::all() : User::whereIn('id', $data['users'])->get();
         try {
         try {
             Notification::send($users, new DynamicNotification($data['via'], $database, $mail));
             Notification::send($users, new DynamicNotification($data['via'], $database, $mail));
-        }
-        catch (Exception $e) {
+        } catch (Exception $e) {
             return redirect()->route('admin.users.notifications')->with('error', __('The attempt to send the email failed with the error: ' . $e->getMessage()));
             return redirect()->route('admin.users.notifications')->with('error', __('The attempt to send the email failed with the error: ' . $e->getMessage()));
         }
         }
 
 

+ 3 - 3
app/Http/Controllers/Api/UserController.php

@@ -43,7 +43,7 @@ class UserController extends Controller
     {
     {
         $this->pterodactyl = new PterodactylClient($ptero_settings);
         $this->pterodactyl = new PterodactylClient($ptero_settings);
     }
     }
-    
+
     /**
     /**
      * Display a listing of the resource.
      * Display a listing of the resource.
      *
      *
@@ -105,7 +105,7 @@ class UserController extends Controller
 
 
         //Update Users Password on Pterodactyl
         //Update Users Password on Pterodactyl
         //Username,Mail,First and Lastname are required aswell
         //Username,Mail,First and Lastname are required aswell
-        $response = $this->pterodactyl->client_admin->patch('/application/users/' . $user->pterodactyl_id, [
+        $response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
             'username' => $request->name,
             'username' => $request->name,
             'first_name' => $request->name,
             'first_name' => $request->name,
             'last_name' => $request->name,
             'last_name' => $request->name,
@@ -280,7 +280,7 @@ class UserController extends Controller
             'referral_code' => $this->createReferralCode(),
             'referral_code' => $this->createReferralCode(),
         ]);
         ]);
 
 
-        $response = $this->pterodactyl->client_admin->post('/application/users', [
+        $response = $this->pterodactyl->application->post('/application/users', [
             'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
             'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
             'username' => $user->name,
             'username' => $user->name,
             'email' => $user->email,
             'email' => $user->email,

+ 5 - 5
app/Http/Controllers/Auth/RegisterController.php

@@ -135,11 +135,12 @@ class RegisterController extends Controller
             'server_limit' => $this->initial_server_limit,
             'server_limit' => $this->initial_server_limit,
             'password' => Hash::make($data['password']),
             'password' => Hash::make($data['password']),
             'referral_code' => $this->createReferralCode(),
             'referral_code' => $this->createReferralCode(),
+            'pterodactyl_id' => Str::uuid(),
 
 
         ]);
         ]);
 
 
-        $response = $this->pterodactyl->client_admin->post('/application/users', [
-            'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
+        $response = $this->pterodactyl->application->post('/application/users', [
+            'external_id' => $user->pterodactyl_id,
             'username' => $user->name,
             'username' => $user->name,
             'email' => $user->email,
             'email' => $user->email,
             'first_name' => $user->name,
             'first_name' => $user->name,
@@ -157,9 +158,8 @@ class RegisterController extends Controller
             ]);
             ]);
         }
         }
 
 
-        $user->update([
-            'pterodactyl_id' => $response->json()['attributes']['id'],
-        ]);
+        // delete activity log for user creation where description = 'created' or 'deleted' and subject_id = user_id
+        DB::table('activity_log')->where('description', 'created')->orWhere('description', 'deleted')->where('subject_id', $user->id)->delete();
 
 
         //INCREMENT REFERRAL-USER CREDITS
         //INCREMENT REFERRAL-USER CREDITS
         if (!empty($data['referral_code'])) {
         if (!empty($data['referral_code'])) {

+ 8 - 8
app/Http/Controllers/ProfileController.php

@@ -78,15 +78,15 @@ class ProfileController extends Controller
         $user = User::findOrFail($id);
         $user = User::findOrFail($id);
 
 
         //update password if necessary
         //update password if necessary
-        if (! is_null($request->input('new_password'))) {
+        if (!is_null($request->input('new_password'))) {
 
 
             //validate password request
             //validate password request
             $request->validate([
             $request->validate([
                 'current_password' => [
                 'current_password' => [
                     'required',
                     'required',
                     function ($attribute, $value, $fail) use ($user) {
                     function ($attribute, $value, $fail) use ($user) {
-                        if (! Hash::check($value, $user->password)) {
-                            $fail('The '.$attribute.' is invalid.');
+                        if (!Hash::check($value, $user->password)) {
+                            $fail('The ' . $attribute . ' is invalid.');
                         }
                         }
                     },
                     },
                 ],
                 ],
@@ -96,7 +96,7 @@ class ProfileController extends Controller
 
 
             //Update Users Password on Pterodactyl
             //Update Users Password on Pterodactyl
             //Username,Mail,First and Lastname are required aswell
             //Username,Mail,First and Lastname are required aswell
-            $response = $this->pterodactyl->client_admin->patch('/application/users/' . $user->pterodactyl_id, [
+            $response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
                 'password' => $request->input('new_password'),
                 'password' => $request->input('new_password'),
                 'username' => $request->input('name'),
                 'username' => $request->input('name'),
                 'first_name' => $request->input('name'),
                 'first_name' => $request->input('name'),
@@ -118,13 +118,13 @@ class ProfileController extends Controller
 
 
         //validate request
         //validate request
         $request->validate([
         $request->validate([
-            'name' => 'required|min:4|max:30|alpha_num|unique:users,name,'.$id.',id',
-            'email' => 'required|email|max:64|unique:users,email,'.$id.',id',
+            'name' => 'required|min:4|max:30|alpha_num|unique:users,name,' . $id . ',id',
+            'email' => 'required|email|max:64|unique:users,email,' . $id . ',id',
             'avatar' => 'nullable',
             'avatar' => 'nullable',
         ]);
         ]);
 
 
         //update avatar
         //update avatar
-        if (! is_null($request->input('avatar'))) {
+        if (!is_null($request->input('avatar'))) {
             $avatar = json_decode($request->input('avatar'));
             $avatar = json_decode($request->input('avatar'));
             if ($avatar->input->size > 3000000) {
             if ($avatar->input->size > 3000000) {
                 abort(500);
                 abort(500);
@@ -140,7 +140,7 @@ class ProfileController extends Controller
         }
         }
 
 
         //update name and email on Pterodactyl
         //update name and email on Pterodactyl
-        $response = $this->pterodactyl->client_admin->patch('/application/users/' . $user->pterodactyl_id, [
+        $response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
             'username' => $request->input('name'),
             'username' => $request->input('name'),
             'first_name' => $request->input('name'),
             'first_name' => $request->input('name'),
             'last_name' => $request->input('name'),
             'last_name' => $request->input('name'),

+ 7 - 7
app/Models/Server.php

@@ -28,9 +28,9 @@ class Server extends Model
     public function getActivitylogOptions(): LogOptions
     public function getActivitylogOptions(): LogOptions
     {
     {
         return LogOptions::defaults()
         return LogOptions::defaults()
-            -> logOnlyDirty()
-            -> logOnly(['*'])
-            -> dontSubmitEmptyLogs();
+            ->logOnlyDirty()
+            ->logOnly(['*'])
+            ->dontSubmitEmptyLogs();
     }
     }
 
 
     /**
     /**
@@ -84,8 +84,8 @@ class Server extends Model
         });
         });
 
 
         static::deleting(function (Server $server) {
         static::deleting(function (Server $server) {
-            $response = $server->pterodactyl->client_admin->delete("/application/servers/{$server->pterodactyl_id}");
-            if ($response->failed() && ! is_null($server->pterodactyl_id)) {
+            $response = $server->pterodactyl->application->delete("/application/servers/{$server->pterodactyl_id}");
+            if ($response->failed() && !is_null($server->pterodactyl_id)) {
                 //only return error when it's not a 404 error
                 //only return error when it's not a 404 error
                 if ($response['errors'][0]['status'] != '404') {
                 if ($response['errors'][0]['status'] != '404') {
                     throw new Exception($response['errors'][0]['code']);
                     throw new Exception($response['errors'][0]['code']);
@@ -99,7 +99,7 @@ class Server extends Model
      */
      */
     public function isSuspended()
     public function isSuspended()
     {
     {
-        return ! is_null($this->suspended);
+        return !is_null($this->suspended);
     }
     }
 
 
     /**
     /**
@@ -107,7 +107,7 @@ class Server extends Model
      */
      */
     public function getPterodactylServer()
     public function getPterodactylServer()
     {
     {
-        return $this->pterodactyl->client_admin->get("/application/servers/{$this->pterodactyl_id}");
+        return $this->pterodactyl->application->get("/application/servers/{$this->pterodactyl_id}");
     }
     }
 
 
     /**
     /**

+ 1 - 21
app/Models/User.php

@@ -122,7 +122,7 @@ class User extends Authenticatable implements MustVerifyEmail
 
 
             $user->discordUser()->delete();
             $user->discordUser()->delete();
 
 
-            $user->pterodactyl->client_admin->delete("/application/users/{$user->pterodactyl_id}");
+            $user->pterodactyl->application->delete("/application/users/{$user->pterodactyl_id}");
         });
         });
     }
     }
 
 
@@ -195,9 +195,6 @@ class User extends Authenticatable implements MustVerifyEmail
         return $this->suspended;
         return $this->suspended;
     }
     }
 
 
-    /**
-     * @throws Exception
-     */
     public function suspend()
     public function suspend()
     {
     {
         foreach ($this->servers as $server) {
         foreach ($this->servers as $server) {
@@ -211,9 +208,6 @@ class User extends Authenticatable implements MustVerifyEmail
         return $this;
         return $this;
     }
     }
 
 
-    /**
-     * @throws Exception
-     */
     public function unSuspend()
     public function unSuspend()
     {
     {
         foreach ($this->getServersWithProduct() as $server) {
         foreach ($this->getServersWithProduct() as $server) {
@@ -241,23 +235,9 @@ class User extends Authenticatable implements MustVerifyEmail
      */
      */
     public function getAvatar()
     public function getAvatar()
     {
     {
-        //TODO loading the images to confirm they exist is causing to much load time. alternative has to be found :) maybe onerror tag on the <img tags>
-        //        if ($this->discordUser()->exists()) {
-        //            if(@getimagesize($this->discordUser->getAvatar())) {
-        //                $avatar = $this->discordUser->getAvatar();
-        //            } else {
-        //                $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
-        //            }
-        //        } else {
-        //            $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
-        //        }
-
         return 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($this->email)));
         return 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($this->email)));
     }
     }
 
 
-    /**
-     * @return string
-     */
     public function creditUsage()
     public function creditUsage()
     {
     {
         $usage = 0;
         $usage = 0;

+ 10 - 0
app/Providers/AppServiceProvider.php

@@ -9,6 +9,7 @@ use Exception;
 use Illuminate\Pagination\Paginator;
 use Illuminate\Pagination\Paginator;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Support\Facades\Schema;
+use Illuminate\Support\Facades\URL;
 use Illuminate\Support\Facades\Validator;
 use Illuminate\Support\Facades\Validator;
 use Illuminate\Support\ServiceProvider;
 use Illuminate\Support\ServiceProvider;
 
 
@@ -54,6 +55,14 @@ class AppServiceProvider extends ServiceProvider
             return $ok;
             return $ok;
         });
         });
 
 
+        // Force HTTPS if APP_URL is set to https
+        if (config('app.url') && parse_url(config('app.url'), PHP_URL_SCHEME) === 'https') {
+            URL::forceScheme('https');
+        }
+
+        // Do not run this code if no APP_KEY is set
+        if (config('app.key') == null) return;
+
         try {
         try {
             if (Schema::hasColumn('useful_links', 'position')) {
             if (Schema::hasColumn('useful_links', 'position')) {
                 $useful_links = UsefulLink::where("position", "like", "%topbar%")->get()->sortby("id");
                 $useful_links = UsefulLink::where("position", "like", "%topbar%")->get()->sortby("id");
@@ -63,6 +72,7 @@ class AppServiceProvider extends ServiceProvider
             Log::error("Couldnt find useful_links. Probably the installation is not completet. " . $e);
             Log::error("Couldnt find useful_links. Probably the installation is not completet. " . $e);
         }
         }
 
 
+
         $settings = $this->app->make(MailSettings::class);
         $settings = $this->app->make(MailSettings::class);
         $settings->setConfig();
         $settings->setConfig();
     }
     }

+ 0 - 5
app/Settings/DiscordSettings.php

@@ -7,15 +7,10 @@ use Spatie\LaravelSettings\Settings;
 class DiscordSettings extends Settings
 class DiscordSettings extends Settings
 {
 {
     public ?string $bot_token;
     public ?string $bot_token;
-
     public ?string $client_id;
     public ?string $client_id;
-
     public ?string $client_secret;
     public ?string $client_secret;
-
     public ?string $guild_id;
     public ?string $guild_id;
-
     public ?string $invite_url;
     public ?string $invite_url;
-
     public ?string $role_id;
     public ?string $role_id;
 
 
     public static function group(): string
     public static function group(): string

+ 22 - 2
app/Settings/GeneralSettings.php

@@ -6,7 +6,7 @@ use Spatie\LaravelSettings\Settings;
 
 
 class GeneralSettings extends Settings
 class GeneralSettings extends Settings
 {
 {
-    public bool $store_enabled = true;
+    public bool $store_enabled;
     public string $credits_display_name;
     public string $credits_display_name;
     public bool $recaptcha_enabled;
     public bool $recaptcha_enabled;
     public string $recaptcha_site_key;
     public string $recaptcha_site_key;
@@ -32,6 +32,26 @@ class GeneralSettings extends Settings
         ];
         ];
     }
     }
 
 
+    /**
+     * Summary of validations array
+     * @return array<string, string>
+     */
+    public static function getValidations()
+    {
+        return [
+            'store_enabled' => 'boolean',
+            'credits_display_name' => 'required|string',
+            'recaptcha_enabled' => 'nullable|boolean',
+            'recaptcha_site_key' => 'nullable|string',
+            'recaptcha_secret_key' => 'nullable|string',
+            'phpmyadmin_url' => 'nullable|string',
+            'alert_enabled' => 'nullable|boolean',
+            'alert_type' => 'required|in:primary,secondary,success,danger,warning,info',
+            'alert_message' => 'required|string',
+            'theme' => 'required|in:default,BlueInfinity' // TODO: themes should be made/loaded dynamically
+        ];
+    }
+
     /**
     /**
      * Summary of optionTypes
      * Summary of optionTypes
      * Only used for the settings page
      * Only used for the settings page
@@ -110,7 +130,7 @@ class GeneralSettings extends Settings
                 'options' => [
                 'options' => [
                     'default' => 'Default',
                     'default' => 'Default',
                     'BlueInfinity' => 'Blue Infinity',
                     'BlueInfinity' => 'Blue Infinity',
-                ],
+                ], // TODO: themes should be made/loaded dynamically
                 'description' => 'The theme to use for the site.'
                 'description' => 'The theme to use for the site.'
             ],
             ],
         ];
         ];

+ 8 - 15
app/Settings/InvoiceSettings.php

@@ -6,21 +6,14 @@ use Spatie\LaravelSettings\Settings;
 
 
 class InvoiceSettings extends Settings
 class InvoiceSettings extends Settings
 {
 {
-    public string $company_address;
-
-    public string $company_mail;
-
-    public string $company_name;
-
-    public string $company_phone;
-
-    public string $company_vat;
-
-    public string $company_website;
-
+    public ?string $company_address;
+    public ?string $company_mail;
+    public ?string $company_name;
+    public ?string $company_phone;
+    public ?string $company_vat;
+    public ?string $company_website;
     public bool $enabled;
     public bool $enabled;
-
-    public string $prefix;
+    public ?string $prefix;
 
 
     public static function group(): string
     public static function group(): string
     {
     {
@@ -40,7 +33,7 @@ class InvoiceSettings extends Settings
             'company_phone' => 'nullable|string',
             'company_phone' => 'nullable|string',
             'company_vat' => 'nullable|string',
             'company_vat' => 'nullable|string',
             'company_website' => 'nullable|string',
             'company_website' => 'nullable|string',
-            'enabled' => 'nullable|string',
+            'enabled' => 'nullable|boolean',
             'prefix' => 'nullable|string',
             'prefix' => 'nullable|string',
         ];
         ];
     }
     }

+ 5 - 9
app/Settings/LocaleSettings.php

@@ -6,14 +6,10 @@ use Spatie\LaravelSettings\Settings;
 
 
 class LocaleSettings extends Settings
 class LocaleSettings extends Settings
 {
 {
-    public string $available;
-
+    public ?string $available;
     public bool $clients_can_change;
     public bool $clients_can_change;
-
-    public string $datatables;
-
+    public ?string $datatables;
     public string $default;
     public string $default;
-
     public bool $dynamic;
     public bool $dynamic;
 
 
     public static function group(): string
     public static function group(): string
@@ -29,10 +25,10 @@ class LocaleSettings extends Settings
     {
     {
         return [
         return [
             'available' => 'nullable|array',
             'available' => 'nullable|array',
-            'clients_can_change' => 'nullable|string',
+            'clients_can_change' => 'nullable|boolean',
             'datatables' => 'nullable|string',
             'datatables' => 'nullable|string',
-            'default' => 'nullable|string',
-            'dynamic' => 'nullable|string',
+            'default' => 'required|in:' . implode(',', config('app.available_locales')),
+            'dynamic' => 'nullable|boolean',
         ];
         ];
     }
     }
 
 

+ 1 - 9
app/Settings/MailSettings.php

@@ -7,22 +7,14 @@ use Spatie\LaravelSettings\Settings;
 class MailSettings extends Settings
 class MailSettings extends Settings
 {
 {
     public ?string $mail_host;
     public ?string $mail_host;
-
     public ?int $mail_port;
     public ?int $mail_port;
-
     public ?string $mail_username;
     public ?string $mail_username;
-
     public ?string $mail_password;
     public ?string $mail_password;
-
     public ?string $mail_encryption;
     public ?string $mail_encryption;
-
     public ?string $mail_from_address;
     public ?string $mail_from_address;
-
     public ?string $mail_from_name;
     public ?string $mail_from_name;
-
     public ?string $mail_mailer;
     public ?string $mail_mailer;
-
-    public ?bool $mail_enabled;
+    public bool $mail_enabled;
 
 
     public static function group(): string
     public static function group(): string
     {
     {

+ 6 - 9
app/Settings/PterodactylSettings.php

@@ -6,12 +6,9 @@ use Spatie\LaravelSettings\Settings;
 
 
 class PterodactylSettings extends Settings
 class PterodactylSettings extends Settings
 {
 {
-    public ?string $admin_token;
-
-    public ?string $user_token;
-
-    public ?string $panel_url;
-
+    public string $admin_token;
+    public string $user_token;
+    public string $panel_url;
     public int $per_page_limit;
     public int $per_page_limit;
 
 
     public static function group(): string
     public static function group(): string
@@ -44,9 +41,9 @@ class PterodactylSettings extends Settings
     public static function getValidations()
     public static function getValidations()
     {
     {
         return [
         return [
-            'panel_url' => 'nullable|string|url',
-            'admin_token' => 'nullable|string',
-            'user_token' => 'nullable|string',
+            'panel_url' => 'required|string|url',
+            'admin_token' => 'required|string',
+            'user_token' => 'required|string',
             'per_page_limit' => 'required|integer|min:1|max:10000',
             'per_page_limit' => 'required|integer|min:1|max:10000',
         ];
         ];
     }
     }

+ 5 - 10
app/Settings/ReferralSettings.php

@@ -7,16 +7,11 @@ use Spatie\LaravelSettings\Settings;
 class ReferralSettings extends Settings
 class ReferralSettings extends Settings
 {
 {
     public string $allowed;
     public string $allowed;
-
     public bool $always_give_commission;
     public bool $always_give_commission;
-
     public bool $enabled;
     public bool $enabled;
-
-    public float $reward;
-
+    public ?float $reward;
     public string $mode;
     public string $mode;
-
-    public int $percentage;
+    public ?int $percentage;
 
 
     public static function group(): string
     public static function group(): string
     {
     {
@@ -30,11 +25,11 @@ class ReferralSettings extends Settings
     public static function getValidations()
     public static function getValidations()
     {
     {
         return [
         return [
-            'allowed' => 'nullable|string',
+            'allowed' => 'required|in:Everyone,Clients',
             'always_give_commission' => 'nullable|boolean',
             'always_give_commission' => 'nullable|boolean',
             'enabled' => 'nullable|boolean',
             'enabled' => 'nullable|boolean',
             'reward' => 'nullable|numeric',
             'reward' => 'nullable|numeric',
-            'mode' => 'nullable|string',
+            'mode' => 'required|in:Commission,Sign-Up,Both',
             'percentage' => 'nullable|numeric',
             'percentage' => 'nullable|numeric',
         ];
         ];
     }
     }
@@ -77,7 +72,7 @@ class ReferralSettings extends Settings
                 'type' => 'select',
                 'type' => 'select',
                 'description' => 'Referral mode.',
                 'description' => 'Referral mode.',
                 'options' => [
                 'options' => [
-                    'comission' => 'Comission',
+                    'commission' => 'Commission',
                     'sign-up' => 'Sign-Up',
                     'sign-up' => 'Sign-Up',
                     'both' => 'Both',
                     'both' => 'Both',
                 ],
                 ],

+ 3 - 6
app/Settings/ServerSettings.php

@@ -7,11 +7,8 @@ use Spatie\LaravelSettings\Settings;
 class ServerSettings extends Settings
 class ServerSettings extends Settings
 {
 {
     public int $allocation_limit;
     public int $allocation_limit;
-
     public bool $creation_enabled;
     public bool $creation_enabled;
-
     public bool $enable_upgrade;
     public bool $enable_upgrade;
-
     public bool $charge_first_hour;
     public bool $charge_first_hour;
 
 
     public static function group(): string
     public static function group(): string
@@ -27,9 +24,9 @@ class ServerSettings extends Settings
     {
     {
         return [
         return [
             'allocation_limit' => 'required|integer|min:0',
             'allocation_limit' => 'required|integer|min:0',
-            'creation_enabled' => 'nullable|string',
-            'enable_upgrade' => 'nullable|string',
-            'charge_first_hour' => 'nullable|string',
+            'creation_enabled' => 'nullable|boolean',
+            'enable_upgrade' => 'nullable|boolean',
+            'charge_first_hour' => 'nullable|boolean',
         ];
         ];
     }
     }
 
 

+ 1 - 2
app/Settings/TicketSettings.php

@@ -7,7 +7,6 @@ use Spatie\LaravelSettings\Settings;
 class TicketSettings extends Settings
 class TicketSettings extends Settings
 {
 {
     public bool $enabled;
     public bool $enabled;
-
     public string $notify;
     public string $notify;
 
 
     public static function group(): string
     public static function group(): string
@@ -22,7 +21,7 @@ class TicketSettings extends Settings
     public static function getValidations()
     public static function getValidations()
     {
     {
         return [
         return [
-            'enabled' => 'nullable|string',
+            'enabled' => 'nullable|boolean',
             'notify' => 'nullable|string',
             'notify' => 'nullable|string',
         ];
         ];
     }
     }

+ 4 - 15
app/Settings/UserSettings.php

@@ -7,27 +7,16 @@ use Spatie\LaravelSettings\Settings;
 class UserSettings extends Settings
 class UserSettings extends Settings
 {
 {
     public float $credits_reward_after_verify_discord;
     public float $credits_reward_after_verify_discord;
-
     public float $credits_reward_after_verify_email;
     public float $credits_reward_after_verify_email;
-
     public bool $force_discord_verification;
     public bool $force_discord_verification;
-
     public bool $force_email_verification;
     public bool $force_email_verification;
-
     public float $initial_credits;
     public float $initial_credits;
-
     public int $initial_server_limit;
     public int $initial_server_limit;
-
     public float $min_credits_to_make_server;
     public float $min_credits_to_make_server;
-
     public int $server_limit_after_irl_purchase;
     public int $server_limit_after_irl_purchase;
-
     public int $server_limit_after_verify_discord;
     public int $server_limit_after_verify_discord;
-
     public int $server_limit_after_verify_email;
     public int $server_limit_after_verify_email;
-
     public bool $register_ip_check;
     public bool $register_ip_check;
-
     public bool $creation_enabled;
     public bool $creation_enabled;
 
 
     public static function group(): string
     public static function group(): string
@@ -44,16 +33,16 @@ class UserSettings extends Settings
         return [
         return [
             'credits_reward_after_verify_discord' => 'required|numeric',
             'credits_reward_after_verify_discord' => 'required|numeric',
             'credits_reward_after_verify_email' => 'required|numeric',
             'credits_reward_after_verify_email' => 'required|numeric',
-            'force_discord_verification' => 'nullable|string',
-            'force_email_verification' => 'nullable|string',
+            'force_discord_verification' => 'nullable|boolean',
+            'force_email_verification' => 'nullable|boolean',
             'initial_credits' => 'required|numeric',
             'initial_credits' => 'required|numeric',
             'initial_server_limit' => 'required|numeric',
             'initial_server_limit' => 'required|numeric',
             'min_credits_to_make_server' => 'required|numeric',
             'min_credits_to_make_server' => 'required|numeric',
             'server_limit_after_irl_purchase' => 'required|numeric',
             'server_limit_after_irl_purchase' => 'required|numeric',
             'server_limit_after_verify_discord' => 'required|numeric',
             'server_limit_after_verify_discord' => 'required|numeric',
             'server_limit_after_verify_email' => 'required|numeric',
             'server_limit_after_verify_email' => 'required|numeric',
-            'register_ip_check' => 'nullable|string',
-            'creation_enabled' => 'nullable|string',
+            'register_ip_check' => 'nullable|boolean',
+            'creation_enabled' => 'nullable|boolean',
         ];
         ];
     }
     }
 
 

+ 9 - 13
app/Settings/WebsiteSettings.php

@@ -9,19 +9,15 @@ class WebsiteSettings extends Settings
 
 
 
 
     public bool $show_imprint;
     public bool $show_imprint;
-
     public bool $show_privacy;
     public bool $show_privacy;
-
     public bool $show_tos;
     public bool $show_tos;
-
     public bool $useful_links_enabled;
     public bool $useful_links_enabled;
     public bool $enable_login_logo;
     public bool $enable_login_logo;
-    public string $seo_title;
-
-    public string $seo_description;
+    public ?string $seo_title;
+    public ?string $seo_description;
     public bool $motd_enabled;
     public bool $motd_enabled;
 
 
-    public string $motd_message;
+    public ?string $motd_message;
 
 
     public static function group(): string
     public static function group(): string
     {
     {
@@ -35,13 +31,13 @@ class WebsiteSettings extends Settings
     public static function getValidations()
     public static function getValidations()
     {
     {
         return [
         return [
-            'motd_enabled' => 'nullable|string',
+            'motd_enabled' => 'nullable|boolean',
             'motd_message' => 'nullable|string',
             'motd_message' => 'nullable|string',
-            'show_imprint' => 'nullable|string',
-            'show_privacy' => 'nullable|string',
-            'show_tos' => 'nullable|string',
-            'useful_links_enabled' => 'nullable|string',
-            'enable_login_logo' => 'nullable|string',
+            'show_imprint' => 'nullable|boolean',
+            'show_privacy' => 'nullable|boolean',
+            'show_tos' => 'nullable|boolean',
+            'useful_links_enabled' => 'nullable|boolean',
+            'enable_login_logo' => 'nullable|boolean',
             'seo_title' => 'nullable|string',
             'seo_title' => 'nullable|string',
             'seo_description' => 'nullable|string',
             'seo_description' => 'nullable|string',
         ];
         ];

+ 32 - 0
database/migrations/2023_04_03_231829_update_users_table.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->string('pterodactyl_id')->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->integer('pterodactyl_id')->nullable->change();
+        });
+    }
+};

+ 0 - 8
database/settings/2023_02_01_164731_create_general_settings.php

@@ -20,7 +20,6 @@ class CreateGeneralSettings extends SettingsMigration
         $this->migrator->add('general.alert_type', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_TYPE") : 'dark');
         $this->migrator->add('general.alert_type', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_TYPE") : 'dark');
         $this->migrator->add('general.alert_message', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_MESSAGE") : '');
         $this->migrator->add('general.alert_message', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_MESSAGE") : '');
         $this->migrator->add('general.theme', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:THEME") : 'default');
         $this->migrator->add('general.theme', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:THEME") : 'default');
-        $this->migrator->add('general.main_site', '');
     }
     }
 
 
     public function down(): void
     public function down(): void
@@ -81,12 +80,6 @@ class CreateGeneralSettings extends SettingsMigration
                 'type' => 'string',
                 'type' => 'string',
                 'description' => 'The URL to your phpMyAdmin installation.'
                 'description' => 'The URL to your phpMyAdmin installation.'
             ],
             ],
-            [
-                'key' => 'SETTINGS::SYSTEM:MAIN_SITE',
-                'value' => $this->getNewValue('main_site'),
-                'type' => 'string',
-                'description' => 'The URL to your main site.'
-            ],
         ]);
         ]);
 
 
         $this->migrator->delete('general.store_enabled');
         $this->migrator->delete('general.store_enabled');
@@ -99,7 +92,6 @@ class CreateGeneralSettings extends SettingsMigration
         $this->migrator->delete('general.alert_type');
         $this->migrator->delete('general.alert_type');
         $this->migrator->delete('general.alert_message');
         $this->migrator->delete('general.alert_message');
         $this->migrator->delete('general.theme');
         $this->migrator->delete('general.theme');
-        $this->migrator->delete('general.main_site');
     }
     }
 
 
     public function getNewValue(string $name)
     public function getNewValue(string $name)

+ 71 - 50
public/install/forms.php

@@ -1,18 +1,15 @@
 <?php
 <?php
 
 
-use DevCoder\DotEnv;
 use PHPMailer\PHPMailer\Exception;
 use PHPMailer\PHPMailer\Exception;
 use PHPMailer\PHPMailer\PHPMailer;
 use PHPMailer\PHPMailer\PHPMailer;
 
 
-require 'dotenv.php';
 require 'phpmailer/Exception.php';
 require 'phpmailer/Exception.php';
 require 'phpmailer/PHPMailer.php';
 require 'phpmailer/PHPMailer.php';
 require 'phpmailer/SMTP.php';
 require 'phpmailer/SMTP.php';
 
 
-(new DotEnv(dirname(__FILE__, 3).'/.env'))->load();
-
 include 'functions.php';
 include 'functions.php';
 
 
+
 if (isset($_POST['checkDB'])) {
 if (isset($_POST['checkDB'])) {
     $values = [
     $values = [
         //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
         //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
@@ -24,9 +21,11 @@ if (isset($_POST['checkDB'])) {
         'DB_CONNECTION' => 'databasedriver',
         'DB_CONNECTION' => 'databasedriver',
     ];
     ];
 
 
+    wh_log('Trying to connect to the Database', 'debug');
+
     $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
     $db = new mysqli($_POST['databasehost'], $_POST['databaseuser'], $_POST['databaseuserpass'], $_POST['database'], $_POST['databaseport']);
     if ($db->connect_error) {
     if ($db->connect_error) {
-        wh_log($db->connect_error);
+        wh_log($db->connect_error, 'error');
         header('LOCATION: index.php?step=2&message=Could not connect to the Database');
         header('LOCATION: index.php?step=2&message=Could not connect to the Database');
         exit();
         exit();
     }
     }
@@ -36,32 +35,36 @@ if (isset($_POST['checkDB'])) {
         // if ($key == "DB_PASSWORD") {
         // if ($key == "DB_PASSWORD") {
         //    $param = '"' . $_POST[$value] . '"';
         //    $param = '"' . $_POST[$value] . '"';
         // }
         // }
-        setEnvironmentValue($key, $param);
+        setenv($key, $param);
     }
     }
 
 
+    wh_log('Database connection successful', 'debug');
     header('LOCATION: index.php?step=2.5');
     header('LOCATION: index.php?step=2.5');
 }
 }
 
 
 if (isset($_POST['checkGeneral'])) {
 if (isset($_POST['checkGeneral'])) {
-    $appname = '"'.$_POST['name'].'"';
+    wh_log('setting app settings', 'debug');
+    $appname = '"' . $_POST['name'] . '"';
     $appurl = $_POST['url'];
     $appurl = $_POST['url'];
 
 
     if (substr($appurl, -1) === '/') {
     if (substr($appurl, -1) === '/') {
         $appurl = substr_replace($appurl, '', -1);
         $appurl = substr_replace($appurl, '', -1);
     }
     }
 
 
-    setEnvironmentValue('APP_NAME', $appname);
-    setEnvironmentValue('APP_URL', $appurl);
+    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=4');
 }
 }
 
 
 if (isset($_POST['feedDB'])) {
 if (isset($_POST['feedDB'])) {
+    wh_log('Feeding the Database', 'debug');
     $logs = '';
     $logs = '';
 
 
-    //$logs .= run_console(putenv('COMPOSER_HOME=' . dirname(__FILE__, 3) . '/vendor/bin/composer'));
+    //$logs .= run_console(setenv('COMPOSER_HOME', dirname(__FILE__, 3) . '/vendor/bin/composer'));
     //$logs .= run_console('composer install --no-dev --optimize-autoloader');
     //$logs .= run_console('composer install --no-dev --optimize-autoloader');
-    if (strpos(getEnvironmentValue('APP_KEY'), 'base64') === false) {
+    if (!str_contains(getenv('APP_KEY'), 'base64')) {
         $logs .= run_console('php artisan key:generate --force');
         $logs .= run_console('php artisan key:generate --force');
     } else {
     } else {
         $logs .= "Key already exists. Skipping\n";
         $logs .= "Key already exists. Skipping\n";
@@ -70,16 +73,19 @@ if (isset($_POST['feedDB'])) {
     $logs .= run_console('php artisan migrate --seed --force');
     $logs .= run_console('php artisan migrate --seed --force');
     $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
     $logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
 
 
-    wh_log($logs);
+    wh_log($logs, 'debug');
 
 
-    if (strpos(getEnvironmentValue('APP_KEY'), 'base64') !== false) {
+    if (str_contains(getenv('APP_KEY'), 'base64')) {
+        wh_log('Feeding the Database successful', 'debug');
         header('LOCATION: index.php?step=3');
         header('LOCATION: index.php?step=3');
     } else {
     } else {
+        wh_log('Feeding the Database failed', 'debug');
         header('LOCATION: index.php?step=2.5&message=There was an error. Please check the .txt file in /var/www/controlpanel/public/install/logs !');
         header('LOCATION: index.php?step=2.5&message=There was an error. Please check the .txt file in /var/www/controlpanel/public/install/logs !');
     }
     }
 }
 }
 
 
 if (isset($_POST['checkSMTP'])) {
 if (isset($_POST['checkSMTP'])) {
+    wh_log('Checking SMTP Settings', 'debug');
     try {
     try {
         $mail = new PHPMailer(true);
         $mail = new PHPMailer(true);
 
 
@@ -103,13 +109,16 @@ if (isset($_POST['checkSMTP'])) {
 
 
         $mail->send();
         $mail->send();
     } catch (Exception $e) {
     } catch (Exception $e) {
+        wh_log($mail->ErrorInfo, 'error');
         header('LOCATION: index.php?step=4&message=Something wasnt right when sending the E-Mail!');
         header('LOCATION: index.php?step=4&message=Something wasnt right when sending the E-Mail!');
         exit();
         exit();
     }
     }
 
 
-    $db = new mysqli(getEnvironmentValue('DB_HOST'), getEnvironmentValue('DB_USERNAME'), getEnvironmentValue('DB_PASSWORD'), getEnvironmentValue('DB_DATABASE'), getEnvironmentValue('DB_PORT'));
+    wh_log('SMTP Settings are correct', 'debug');
+    wh_log('Updating Database', 'debug');
+    $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
     if ($db->connect_error) {
     if ($db->connect_error) {
-        wh_log($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=4&message=Could not connect to the Database: ');
         exit();
         exit();
     }
     }
@@ -118,20 +127,23 @@ if (isset($_POST['checkSMTP'])) {
         'mail_host' => $_POST['host'],
         'mail_host' => $_POST['host'],
         'mail_port' => $_POST['port'],
         'mail_port' => $_POST['port'],
         'mail_username' => $_POST['user'],
         'mail_username' => $_POST['user'],
-        'mail_password' => $_POST['pass'],
+        'mail_password' => encryptSettingsValue($_POST['pass']),
         'mail_encryption' => $_POST['encryption'],
         'mail_encryption' => $_POST['encryption'],
         'mail_from_address' => $_POST['user'],
         'mail_from_address' => $_POST['user'],
     ];
     ];
 
 
     foreach ($values as $key => $value) {
     foreach ($values as $key => $value) {
-        $query = 'UPDATE `'.getEnvironmentValue('DB_DATABASE')."`.`settings` SET `payload` = '$value' WHERE `name` = '$key' AND `group` = mail";
+        $query = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '$value' WHERE `name` = '$key' AND `group` = mail";
         $db->query($query);
         $db->query($query);
     }
     }
 
 
+    wh_log('Database updated', 'debug');
     header('LOCATION: index.php?step=5');
     header('LOCATION: index.php?step=5');
 }
 }
 
 
 if (isset($_POST['checkPtero'])) {
 if (isset($_POST['checkPtero'])) {
+    wh_log('Checking Pterodactyl Settings', 'debug');
+
     $url = $_POST['url'];
     $url = $_POST['url'];
     $key = $_POST['key'];
     $key = $_POST['key'];
     $clientkey = $_POST['clientkey'];
     $clientkey = $_POST['clientkey'];
@@ -140,67 +152,75 @@ if (isset($_POST['checkPtero'])) {
         $url = substr_replace($url, '', -1);
         $url = substr_replace($url, '', -1);
     }
     }
 
 
-    $callpteroURL = $url.'/api/client/account';
+    $callpteroURL = $url . '/api/client/account';
     $call = curl_init();
     $call = curl_init();
 
 
     curl_setopt($call, CURLOPT_URL, $callpteroURL);
     curl_setopt($call, CURLOPT_URL, $callpteroURL);
     curl_setopt($call, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($call, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($call, CURLOPT_HTTPHEADER, [
     curl_setopt($call, CURLOPT_HTTPHEADER, [
-        'Accept: application/json',
+        'Accept: Application/vnd.pterodactyl.v1+json',
         'Content-Type: application/json',
         'Content-Type: application/json',
-        'Authorization: Bearer '.$clientkey,
+        'Authorization: Bearer ' . $clientkey,
     ]);
     ]);
     $callresponse = curl_exec($call);
     $callresponse = curl_exec($call);
     $callresult = json_decode($callresponse, true);
     $callresult = json_decode($callresponse, true);
     curl_close($call); // Close the connection
     curl_close($call); // Close the connection
 
 
-    $pteroURL = $url.'/api/application/users';
+    $pteroURL = $url . '/api/application/users';
     $ch = curl_init();
     $ch = curl_init();
 
 
     curl_setopt($ch, CURLOPT_URL, $pteroURL);
     curl_setopt($ch, CURLOPT_URL, $pteroURL);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
-        'Accept: application/json',
+        'Accept: Application/vnd.pterodactyl.v1+json',
         'Content-Type: application/json',
         'Content-Type: application/json',
-        'Authorization: Bearer '.$key,
+        'Authorization: Bearer ' . $key,
     ]);
     ]);
     $response = curl_exec($ch);
     $response = curl_exec($ch);
     $result = json_decode($response, true);
     $result = json_decode($response, true);
     curl_close($ch); // Close the connection
     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=Couldnt connect to Pterodactyl. Make sure your API key has all read and write permissions!');
-        wh_log('API CALL ERROR: '.$result['errors'][0]['code']);
+    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!');
+        wh_log('API CALL ERROR: ' . $result['errors'][0]['code'], 'error');
         exit();
         exit();
-    } elseif (! is_array($callresult) or in_array($result['errors'][0]['code'], $result) or $callresult['attributes']['admin'] == false) {
+    } 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!');
         header('LOCATION: index.php?step=5&message=Your ClientAPI Key is wrong or the account is not an admin!');
-        wh_log('API CALL ERROR: '.$result['errors'][0]['code']);
+        wh_log('API CALL ERROR: ' . $callresult['errors'][0]['code'], 'error');
         exit();
         exit();
     } else {
     } else {
-        $query1 = 'UPDATE `'.getEnvironmentValue('DB_DATABASE')."`.`settings` SET `payload` = '$url' WHERE (`name` = 'panel_url' AND `group` = 'pterodactyl')";
-        $query2 = 'UPDATE `'.getEnvironmentValue('DB_DATABASE')."`.`settings` SET `payload` = '$key' WHERE (`name` = 'admin_token' AND `group` = 'pterodactyl')";
-        $query3 = 'UPDATE `'.getEnvironmentValue('DB_DATABASE')."`.`settings` SET `payload` = '$clientkey' WHERE (`name` = 'user_token' AND `group` = 'pterodactyl')";
+        wh_log('Pterodactyl Settings are correct', 'debug');
+        wh_log('Updating Database', 'debug');
+
+        $key = encryptSettingsValue($key);
+        $clientkey = encryptSettingsValue($clientkey);
 
 
-        $db = new mysqli(getEnvironmentValue('DB_HOST'), getEnvironmentValue('DB_USERNAME'), getEnvironmentValue('DB_PASSWORD'), getEnvironmentValue('DB_DATABASE'), getEnvironmentValue('DB_PORT'));
+        $query1 = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '" . json_encode($url) . "' WHERE (`name` = 'panel_url' AND `group` = 'pterodactyl')";
+        $query2 = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '" . json_encode($key) . "' WHERE (`name` = 'admin_token' AND `group` = 'pterodactyl')";
+        $query3 = 'UPDATE `' . getenv('DB_DATABASE') . "`.`settings` SET `payload` = '" . json_encode($clientkey) . "' WHERE (`name` = 'user_token' AND `group` = 'pterodactyl')";
+
+        $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
         if ($db->connect_error) {
         if ($db->connect_error) {
-            wh_log($db->connect_error);
+            wh_log($db->connect_error, 'error');
             header('LOCATION: index.php?step=5&message=Could not connect to the Database');
             header('LOCATION: index.php?step=5&message=Could not connect to the Database');
             exit();
             exit();
         }
         }
 
 
         if ($db->query($query1) && $db->query($query2) && $db->query($query3)) {
         if ($db->query($query1) && $db->query($query2) && $db->query($query3)) {
+            wh_log('Database updated', 'debug');
             header('LOCATION: index.php?step=6');
             header('LOCATION: index.php?step=6');
         } else {
         } else {
-            wh_log($db->error);
+            wh_log($db->error, 'error');
             header('LOCATION: index.php?step=5&message=Something went wrong when communicating with the Database!');
             header('LOCATION: index.php?step=5&message=Something went wrong when communicating with the Database!');
         }
         }
     }
     }
 }
 }
 
 
 if (isset($_POST['createUser'])) {
 if (isset($_POST['createUser'])) {
-    $db = new mysqli(getEnvironmentValue('DB_HOST'), getEnvironmentValue('DB_USERNAME'), getEnvironmentValue('DB_PASSWORD'), getEnvironmentValue('DB_DATABASE'), getEnvironmentValue('DB_PORT'));
+    wh_log('Creating User', 'debug');
+    $db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'), getenv('DB_PORT'));
     if ($db->connect_error) {
     if ($db->connect_error) {
-        wh_log($db->connect_error);
+        wh_log($db->connect_error, 'error');
         header('LOCATION: index.php?step=6&message=Could not connect to the Database');
         header('LOCATION: index.php?step=6&message=Could not connect to the Database');
         exit();
         exit();
     }
     }
@@ -209,10 +229,11 @@ if (isset($_POST['createUser'])) {
     $pass = $_POST['pass'];
     $pass = $_POST['pass'];
     $repass = $_POST['repass'];
     $repass = $_POST['repass'];
 
 
-    $key = $db->query('SELECT `payload` FROM `'.getEnvironmentValue('DB_DATABASE')."`.`settings` WHERE `name` = 'admin_token' AND `group` = 'pterodactyl'")->fetch_assoc();
-    $pterobaseurl = $db->query('SELECT `payload` FROM `'.getEnvironmentValue('DB_DATABASE')."`.`settings` WHERE `name` = 'panel_url' AND `group` = 'pterodactyl'")->fetch_assoc();
+    $key = $db->query('SELECT `payload` FROM `' . getenv('DB_DATABASE') . "`.`settings` WHERE `name` = 'admin_token' AND `group` = 'pterodactyl'")->fetch_assoc();
+    $key = encryptSettingsValue($key['value']);
+    $pterobaseurl = $db->query('SELECT `payload` FROM `' . getenv('DB_DATABASE') . "`.`settings` WHERE `name` = 'panel_url' AND `group` = 'pterodactyl'")->fetch_assoc();
 
 
-    $pteroURL = $pterobaseurl['value'].'/api/application/users/'.$pteroID;
+    $pteroURL = $pterobaseurl['value'] . '/api/application/users/' . $pteroID;
     $ch = curl_init();
     $ch = curl_init();
 
 
     curl_setopt($ch, CURLOPT_URL, $pteroURL);
     curl_setopt($ch, CURLOPT_URL, $pteroURL);
@@ -220,14 +241,14 @@ if (isset($_POST['createUser'])) {
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
         'Accept: application/json',
         'Accept: application/json',
         'Content-Type: application/json',
         'Content-Type: application/json',
-        'Authorization: Bearer '.$key['value'],
+        'Authorization: Bearer ' . $key,
     ]);
     ]);
     $response = curl_exec($ch);
     $response = curl_exec($ch);
     $result = json_decode($response, true);
     $result = json_decode($response, true);
     curl_close($ch); // Close the connection
     curl_close($ch); // Close the connection
 
 
-    if (! $result['attributes']['email']) {
-        header('LOCATION: index.php?step=6&message=Could not find the user with pterodactyl ID '.$pteroID);
+    if (!$result['attributes']['email']) {
+        header('LOCATION: index.php?step=6&message=Could not find the user with pterodactyl ID ' . $pteroID);
         exit();
         exit();
     }
     }
     if ($pass !== $repass) {
     if ($pass !== $repass) {
@@ -239,7 +260,7 @@ if (isset($_POST['createUser'])) {
     $name = $result['attributes']['username'];
     $name = $result['attributes']['username'];
     $pass = password_hash($pass, PASSWORD_DEFAULT);
     $pass = password_hash($pass, PASSWORD_DEFAULT);
 
 
-    $pteroURL = $pterobaseurl['value'].'/api/application/users/'.$pteroID;
+    $pteroURL = $pterobaseurl['value'] . '/api/application/users/' . $pteroID;
     $ch = curl_init();
     $ch = curl_init();
 
 
     curl_setopt($ch, CURLOPT_URL, $pteroURL);
     curl_setopt($ch, CURLOPT_URL, $pteroURL);
@@ -247,7 +268,7 @@ if (isset($_POST['createUser'])) {
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
     curl_setopt($ch, CURLOPT_HTTPHEADER, [
         'Accept: application/json',
         'Accept: application/json',
         'Content-Type: application/json',
         'Content-Type: application/json',
-        'Authorization: Bearer '.$key['value'],
+        'Authorization: Bearer ' . $key['value'],
     ]);
     ]);
     curl_setopt($ch, CURLOPT_POSTFIELDS, [
     curl_setopt($ch, CURLOPT_POSTFIELDS, [
         'email' => $mail,
         'email' => $mail,
@@ -260,19 +281,19 @@ if (isset($_POST['createUser'])) {
     $result = json_decode($response, true);
     $result = json_decode($response, true);
     curl_close($ch); // Close the connection
     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=Couldnt connect to Pterodactyl. Make sure your API key has all read and write permissions!');
+    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();
         exit();
     }
     }
 
 
     $random = generateRandomString();
     $random = generateRandomString();
-    $query1 = 'INSERT INTO `'.getEnvironmentValue('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')";
+    $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')";
 
 
     if ($db->query($query1)) {
     if ($db->query($query1)) {
-        wh_log('[USER MAKER] Created user with Email '.$mail.' and pterodactyl ID '.$pteroID);
+        wh_log('Created user with Email ' . $mail . ' and pterodactyl ID ' . $pteroID, 'info');
         header('LOCATION: index.php?step=7');
         header('LOCATION: index.php?step=7');
     } else {
     } else {
-        wh_log($db->error);
+        wh_log($db->error, 'error');
         header('LOCATION: index.php?step=6&message=Something went wrong when communicating with the Database');
         header('LOCATION: index.php?step=6&message=Something went wrong when communicating with the Database');
     }
     }
-}
+}

+ 180 - 40
public/install/functions.php

@@ -1,6 +1,17 @@
 <?php
 <?php
+require '../../vendor/autoload.php';
+require 'dotenv.php';
 
 
-$required_extentions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl'];
+use DevCoder\DotEnv;
+use Illuminate\Encryption\Encrypter;
+use Illuminate\Support\Str;
+use Monolog\Formatter\LineFormatter;
+use Monolog\Handler\StreamHandler;
+use Monolog\Logger;
+
+(new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
+
+$required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl'];
 
 
 $requirements = [
 $requirements = [
     'minPhp' => '8.1',
     'minPhp' => '8.1',
@@ -8,84 +19,140 @@ $requirements = [
     'mysql' => '5.7.22',
     'mysql' => '5.7.22',
 ];
 ];
 
 
-function checkPhpVersion()
+/**
+ * Check if the minimum PHP version is present
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function checkPhpVersion(): string
 {
 {
     global $requirements;
     global $requirements;
+
+    wh_log('php version: ' . phpversion(), 'debug');
     if (version_compare(phpversion(), $requirements['minPhp'], '>=') && version_compare(phpversion(), $requirements['maxPhp'], '<=')) {
     if (version_compare(phpversion(), $requirements['minPhp'], '>=') && version_compare(phpversion(), $requirements['maxPhp'], '<=')) {
         return 'OK';
         return 'OK';
     }
     }
 
 
     return 'not OK';
     return 'not OK';
 }
 }
-function checkWriteable()
+
+/**
+ * Check if the environment file is writable
+ * @return bool Returns true on writable and false on not writable.
+ */
+function checkWriteable(): bool
 {
 {
     return is_writable('../../.env');
     return is_writable('../../.env');
 }
 }
-function checkHTTPS()
+
+/**
+ * Check if the server runs using HTTPS
+ * @return bool Returns true on HTTPS or false on HTTP.
+ */
+function checkHTTPS(): bool
 {
 {
-    return (! empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
-        || $_SERVER['SERVER_PORT'] == 443;
+    $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
+    wh_log('https:', 'debug', (array)$isHttps);
+    return $isHttps;
 }
 }
 
 
-function getMySQLVersion()
+/**
+ * Check if MySQL is installed and runs the correct version using a shell command
+ * @return mixed|string 'OK' if required version is met, returns MySQL version if not met.
+ */
+function getMySQLVersion(): mixed
 {
 {
     global $requirements;
     global $requirements;
 
 
-    $output = shell_exec('mysql -V');
+    wh_log('attempting to get mysql version', 'debug');
+
+    $output = shell_exec('mysql -V') ?? '';
     preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
     preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
 
 
     $versionoutput = $version[0] ?? '0';
     $versionoutput = $version[0] ?? '0';
+    wh_log('mysql version: ' . $versionoutput, 'debug');
 
 
     return intval($versionoutput) > intval($requirements['mysql']) ? 'OK' : $versionoutput;
     return intval($versionoutput) > intval($requirements['mysql']) ? 'OK' : $versionoutput;
 }
 }
 
 
-function getZipVersion()
+/**
+ * Check if zip is installed using a shell command
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function getZipVersion(): string
 {
 {
-    $output = shell_exec('zip  -v');
+    wh_log('attempting to get zip version', 'debug');
+    $output = shell_exec('zip  -v') ?? '';
     preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
     preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
 
 
     $versionoutput = $version[0] ?? 0;
     $versionoutput = $version[0] ?? 0;
+    wh_log('zip version: ' . $versionoutput, 'debug');
 
 
     return $versionoutput != 0 ? 'OK' : 'not OK';
     return $versionoutput != 0 ? 'OK' : 'not OK';
 }
 }
 
 
-function getGitVersion()
+/**
+ * Check if git is installed using a shell command
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function getGitVersion(): string
 {
 {
-    $output = shell_exec('git  --version');
+    wh_log('attempting to get git version', 'debug');
+    $output = shell_exec('git  --version') ?? '';
     preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
     preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
 
 
     $versionoutput = $version[0] ?? 0;
     $versionoutput = $version[0] ?? 0;
+    wh_log('git version: ' . $versionoutput, 'debug');
 
 
     return $versionoutput != 0 ? 'OK' : 'not OK';
     return $versionoutput != 0 ? 'OK' : 'not OK';
 }
 }
 
 
-function getTarVersion()
+/**
+ * Check if tar is installed using a shell command
+ * @return string 'OK' on success and 'not OK' on failure.
+ */
+function getTarVersion(): string
 {
 {
-    $output = shell_exec('tar  --version');
+    wh_log('attempting to get tar version', 'debug');
+    $output = shell_exec('tar  --version') ?? '';
     preg_match('@[0-9]+\.[0-9]+@', $output, $version);
     preg_match('@[0-9]+\.[0-9]+@', $output, $version);
 
 
     $versionoutput = $version[0] ?? 0;
     $versionoutput = $version[0] ?? 0;
+    wh_log('tar version: ' . $versionoutput, 'debug');
 
 
     return $versionoutput != 0 ? 'OK' : 'not OK';
     return $versionoutput != 0 ? 'OK' : 'not OK';
 }
 }
 
 
-function checkExtensions()
+/**
+ * Check all extensions to see if they have loaded or not
+ * @return array Returns an array of extensions that failed to load.
+ */
+function checkExtensions(): array
 {
 {
-    global $required_extentions;
+    global $required_extensions;
+
+    wh_log('checking extensions', 'debug');
 
 
     $not_ok = [];
     $not_ok = [];
     $extentions = get_loaded_extensions();
     $extentions = get_loaded_extensions();
 
 
-    foreach ($required_extentions as $ext) {
-        if (! preg_grep('/^(?=.*'.$ext.').*$/', $extentions)) {
+    foreach ($required_extensions as $ext) {
+        if (!preg_grep('/^(?=.*' . $ext . ').*$/', $extentions)) {
             array_push($not_ok, $ext);
             array_push($not_ok, $ext);
         }
         }
     }
     }
 
 
+    wh_log('loaded extensions:', 'debug', $extentions);
+    wh_log('failed extensions:', 'debug', $not_ok);
     return $not_ok;
     return $not_ok;
 }
 }
 
 
-function setEnvironmentValue($envKey, $envValue)
+/**
+ * Sets the environment variable into the env file
+ * @param string $envKey The environment key to set or modify
+ * @param string $envValue The environment variable to set
+ * @return bool true on success or false on failure.
+ */
+function setenv($envKey, $envValue)
 {
 {
     $envFile = dirname(__FILE__, 3).'/.env';
     $envFile = dirname(__FILE__, 3).'/.env';
     $str = file_get_contents($envFile);
     $str = file_get_contents($envFile);
@@ -102,41 +169,114 @@ function setEnvironmentValue($envKey, $envValue)
     fclose($fp);
     fclose($fp);
 }
 }
 
 
-function getEnvironmentValue($envKey)
+/**
+ * Encrypt the given value
+ * @param mixed $value The variable to be encrypted
+ * @param bool $serialize If the encryption should be serialized
+ * @return string Returns the encrypted variable.
+ */
+function encryptSettingsValue(mixed $value, $serialize = true): string
 {
 {
-    $envFile = dirname(__FILE__, 3).'/.env';
-    $str = file_get_contents($envFile);
+    $appKey = getenv('APP_KEY');
+    $appKey = base64_decode(Str::after($appKey, 'base64:'));
+    $encrypter = new Encrypter($appKey);
+    $encryptedKey = $encrypter->encrypt($value, $serialize);
 
 
-    $str .= "\n"; // In case the searched variable is in the last line without \n
-    $keyPosition = strpos($str, "{$envKey}=");
-    $endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
-    $oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
-    $value = substr($oldLine, strpos($oldLine, '=') + 1);
+    return $encryptedKey;
+}
 
 
-    return $value;
+/**
+ * Decrypt the given value
+ * @param mixed $payload The payload to be decrypted
+ * @param bool $unserialize If the encryption should be unserialized
+ * @return mixed Returns the decrypted variable on success, throws otherwise.
+ */
+
+function decryptSettingsValue(mixed $payload, $unserialize = true)
+{
+    $appKey = getenv('APP_KEY');
+    $appKey = base64_decode(Str::after($appKey, 'base64:'));
+    $encrypter = new Encrypter($appKey);
+    $decryptedKey = $encrypter->decrypt($payload, $unserialize);
+
+    return $decryptedKey;
 }
 }
 
 
-function run_console($command)
+/**
+ * Run a shell command
+ * @param string $command The command string to run
+ * @param array|null $descriptors [optional]<p>
+ * An indexed array where the key represents the descriptor number and the value represents how PHP will pass that descriptor to the child process. 0 is stdin, 1 is stdout, while 2 is stderr.
+ * Default descriptors when null are 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']
+ * </p>
+ * @param string|null $cwd [optional] <p>
+ * The initial working dir for the command. This must be an
+ * absolute directory path, or null
+ * if you want to use the default value (the working dir of the current
+ * PHP process)
+ * </p>
+ * @param array|null $options [optional] <p>
+ * Allows you to specify additional options.
+ * @link https://www.php.net/manual/en/function.proc-open.php proc_open
+ * </p>
+ * @return false|string|null Returns the result from the command.
+ */
+function run_console(string $command, array $descriptors = null, string $cwd = null, array $options = null)
 {
 {
+    wh_log('running command: ' . $command, 'debug');
+
     $path = dirname(__FILE__, 3);
     $path = dirname(__FILE__, 3);
-    $cmd = "cd '$path' && bash -c 'exec -a ServerCPP $command' 2>&1";
+    $descriptors = $descriptors ?? [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
+    $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", $descriptors, $pipes, $cwd, null, $options);
 
 
-    return shell_exec($cmd);
+    wh_log('command result: ' . stream_get_contents($pipes[1]), 'debug');
+    return stream_get_contents($pipes[1]);
 }
 }
 
 
-function wh_log($log_msg)
+/**
+ * Log to the default laravel.log file
+ * @param string $message The message to log
+ * @param string $level The log level to use (debug, info, warning, error, critical)
+ * @param array $context [optional] The context to log extra information
+ * @return void
+ */
+function wh_log(string $message, string $level = 'info', array $context = []): void
 {
 {
-    $log_filename = 'logs';
-    if (! file_exists($log_filename)) {
-        // create directory/folder uploads.
-        mkdir($log_filename, 0777, true);
+    $formatter = new LineFormatter(null, null, true, true);
+    $stream = new StreamHandler(dirname(__FILE__, 3) . '/storage/logs/installer.log', Logger::DEBUG);
+    $stream->setFormatter($formatter);
+
+    $log = new Logger('ControlPanel');
+    $log->pushHandler($stream);
+
+    switch (strtolower($level)) {
+        case 'debug': // Only log debug messages if APP_DEBUG is true
+            if(getenv('APP_DEBUG') === false) return;
+            $log->debug($message, $context);
+            break;
+        case 'info':
+            $log->info($message, $context);
+            break;
+        case 'warning':
+            $log->warning($message, $context);
+            break;
+        case 'error':
+            $log->error($message, $context);
+            break;
+        case 'critical':
+            $log->critical($message, $context);
+            break;
     }
     }
-    $log_file_data = $log_filename.'/installer.log';
-    // if you don't add `FILE_APPEND`, the file will be erased each time you add a log
-    file_put_contents($log_file_data, '['.date('h:i:s').'] '.$log_msg."\n", FILE_APPEND);
+    // Prevent memory leaks by resetting the logger
+    $log->reset();
 }
 }
 
 
-function generateRandomString($length = 8)
+/**
+ * Generate a random string
+ * @param int $length The length of the random string
+ * @return string The randomly generated string.
+ */
+function generateRandomString(int $length = 8): string
 {
 {
     $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
     $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
     $charactersLength = strlen($characters);
     $charactersLength = strlen($characters);

+ 305 - 301
public/install/index.php

@@ -52,8 +52,8 @@ $cardheader = '
         </div>
         </div>
         <div class="card-body bg-light">';
         <div class="card-body bg-light">';
 
 
-if (! isset($_GET['step'])) {
-    if (! file_exists('../../.env')) {
+if (!isset($_GET['step'])) {
+    if (!file_exists('../../.env')) {
         echo run_console('cp .env.example .env');
         echo run_console('cp .env.example .env');
     }
     }
     echo $cardheader; ?>
     echo $cardheader; ?>
@@ -71,11 +71,11 @@ if (! isset($_GET['step'])) {
 
 
     <p class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'notok'; ?>"> Missing
     <p class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'notok'; ?>"> Missing
         php-extentions: <?php echo count(checkExtensions()) == 0 ? 'none' : '';
         php-extentions: <?php echo count(checkExtensions()) == 0 ? 'none' : '';
-    foreach (checkExtensions() as $ext) {
-        echo $ext.', ';
-    }
+        foreach (checkExtensions() as $ext) {
+            echo $ext . ', ';
+        }
 
 
-    echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?></p>
+        echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?></p>
 
 
 
 
     <!-- <p class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'notok'; ?>"> Zip
     <!-- <p class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'notok'; ?>"> Zip
@@ -98,70 +98,70 @@ if (! isset($_GET['step'])) {
 }
 }
 if (isset($_GET['step']) && $_GET['step'] == 2) {
 if (isset($_GET['step']) && $_GET['step'] == 2) {
     echo $cardheader; ?>
     echo $cardheader; ?>
-<p class="login-box-msg">Lets start with your Database</p>
-<?php if (isset($_GET['message'])) {
-        echo "<p class='notok'>".$_GET['message'].'</p>';
+    <p class="login-box-msg">Lets start with your Database</p>
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='notok'>" . $_GET['message'] . '</p>';
     } ?>
     } ?>
 
 
-<form method="POST" enctype="multipart/form-data" class="mb-3"
-      action="/install/forms.php" name="checkDB">
-
-    <div class="row">
-        <div class="col-md-12">
-            <div class="form-group">
-                <div class="custom-control mb-3">
-                    <label for="database">Database Driver</label>
-                    <input x-model="databasedriver" id="databasedriver" name="databasedriver"
-                           type="text" required
-                           value="mysql" class="form-control">
+    <form method="POST" enctype="multipart/form-data" class="mb-3"
+          action="/install/forms.php" name="checkDB">
+
+        <div class="row">
+            <div class="col-md-12">
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="database">Database Driver</label>
+                        <input x-model="databasedriver" id="databasedriver" name="databasedriver"
+                               type="text" required
+                               value="mysql" class="form-control">
+                    </div>
                 </div>
                 </div>
-            </div>
-            <div class="form-group">
-                <div class="custom-control mb-3">
-                    <label for="databasehost">Database Host</label>
-                    <input x-model="databasehost" id="databasehost" name="databasehost" type="text"
-                           required
-                           value="127.0.0.1" class="form-control">
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="databasehost">Database Host</label>
+                        <input x-model="databasehost" id="databasehost" name="databasehost" type="text"
+                               required
+                               value="127.0.0.1" class="form-control">
+                    </div>
                 </div>
                 </div>
-            </div>
-            <div class="form-group">
-                <div class="custom-control mb-3">
-                    <label for="databaseport">Database Port</label>
-                    <input x-model="databaseport" id="databaseport" name="databaseport"
-                           type="number" required
-                           value="3306" class="form-control">
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="databaseport">Database Port</label>
+                        <input x-model="databaseport" id="databaseport" name="databaseport"
+                               type="number" required
+                               value="3306" class="form-control">
+                    </div>
                 </div>
                 </div>
-            </div>
-            <div class="form-group">
-                <div class="custom-control mb-3">
-                    <label for="databaseuser">Database User</label>
-                    <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text"
-                           required
-                           value="controlpaneluser" class="form-control">
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="databaseuser">Database User</label>
+                        <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text"
+                               required
+                               value="controlpaneluser" class="form-control">
+                    </div>
                 </div>
                 </div>
-            </div>
-            <div class="form-group">
-                <div class="custom-control mb-3">
-                    <label for="databaseuserpass">Database User Password</label>
-                    <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass"
-                           type="text" required
-                           class="form-control ">
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="databaseuserpass">Database User Password</label>
+                        <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass"
+                               type="text" required
+                               class="form-control ">
+                    </div>
                 </div>
                 </div>
-            </div>
 
 
-            <div class="form-group">
-                <div class="custom-control mb-3">
-                    <label for="database">Database</label>
-                    <input x-model="database" id="database" name="database" type="text" required
-                           value="controlpanel" class="form-control">
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="database">Database</label>
+                        <input x-model="database" id="database" name="database" type="text" required
+                               value="controlpanel" class="form-control">
+                    </div>
                 </div>
                 </div>
+
             </div>
             </div>
 
 
+            <button class="btn btn-primary" name="checkDB">Submit</button>
         </div>
         </div>
-
-        <button class="btn btn-primary" name="checkDB">Submit</button>
-    </div>
-</form>
+    </form>
     </div>
     </div>
 
 
 
 
@@ -169,287 +169,291 @@ if (isset($_GET['step']) && $_GET['step'] == 2) {
 
 
     <?php
     <?php
 }
 }
-    if (isset($_GET['step']) && $_GET['step'] == 2.5) {
-        echo $cardheader; ?>
+if (isset($_GET['step']) && $_GET['step'] == 2.5) {
+    echo $cardheader; ?>
     <p class="login-box-msg">Lets feed your Database and generate some security keys!</p>
     <p class="login-box-msg">Lets feed your Database and generate some security keys!</p>
     <p> This process might take a while. Please do not refresh or close this page!</p>
     <p> This process might take a while. Please do not refresh or close this page!</p>
     <?php if (isset($_GET['message'])) {
     <?php if (isset($_GET['message'])) {
-            echo "<p class='notok'>".$_GET['message'].'</p>';
-        } ?>
+        echo "<p class='notok'>" . $_GET['message'] . '</p>';
+    } ?>
 
 
     <form method="POST" enctype="multipart/form-data" class="mb-3"
     <form method="POST" enctype="multipart/form-data" class="mb-3"
           action="/install/forms.php" name="feedDB">
           action="/install/forms.php" name="feedDB">
 
 
 
 
         <button class="btn btn-primary" name="feedDB">Submit</button>
         <button class="btn btn-primary" name="feedDB">Submit</button>
-        </div>
-        </div>
+    </form>
+    </div>
 
 
 
 
-        </div>
+    </div>
 
 
-        <?php
-    }
+    <?php
+}
 
 
-        if (isset($_GET['step']) && $_GET['step'] == 3) {
-            echo $cardheader; ?>
-        <p class="login-box-msg">Tell us something about your Host</p>
+if (isset($_GET['step']) && $_GET['step'] == 3) {
+    echo $cardheader; ?>
+    <p class="login-box-msg">Tell us something about your Host</p>
 
 
-        <?php if (isset($_GET['message'])) {
-                echo "<p class='notok'>".$_GET['message'].'</p>';
-            } ?>
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='notok'>" . $_GET['message'] . '</p>';
+    } ?>
 
 
-        <form method="POST" enctype="multipart/form-data" class="mb-3"
-              action="/install/forms.php" name="checkGeneral">
+    <form method="POST" enctype="multipart/form-data" class="mb-3"
+          action="/install/forms.php" name="checkGeneral">
 
 
 
 
-            <div class="row">
-                <div class="col-md-12">
-                    <div class="form-group">
-                        <div class="custom-control mb-3">
-                            <label for="database">Your Dashboard URL</label>
-                            <input id="url" name="url"
-                                   type="text" required
-                                   value="<?php echo 'https://'.$_SERVER['SERVER_NAME']; ?>" class="form-control">
-                        </div>
+        <div class="row">
+            <div class="col-md-12">
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="database">Your Dashboard URL</label>
+                        <input id="url" name="url"
+                               type="text" required
+                               value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>" class="form-control">
                     </div>
                     </div>
-                    <div class="form-group">
-                        <div class="custom-control mb-3">
-                            <label for="name">Your Host-Name</label>
-                            <input id="name" name="name" type="text"
-                                   required
-                                   value="Controlpanel.gg" class="form-control">
-                        </div>
+                </div>
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="name">Your Host-Name</label>
+                        <input id="name" name="name" type="text"
+                               required
+                               value="" class="form-control">
                     </div>
                     </div>
-
                 </div>
                 </div>
 
 
-                <button class="btn btn-primary" name="checkGeneral">Submit</button>
-            </div>
-        </form>
             </div>
             </div>
 
 
+            <button class="btn btn-primary" name="checkGeneral">Submit</button>
+        </div>
+    </form>
+    </div>
 
 
-            </div>
 
 
-            <?php
-        }
-            if (isset($_GET['step']) && $_GET['step'] == 4) {
-                echo $cardheader; ?>
-            <p class="login-box-msg">Lets get your E-Mails going! </p>
-            <p class="login-box-msg">This might take a few seconds when submitted! </p>
-
-            <?php if (isset($_GET['message'])) {
-                    echo "<p class='notok'>".$_GET['message'].'</p>';
-                } ?>
-
-            <form method="POST" enctype="multipart/form-data" class="mb-3"
-
-                  action="/install/forms.php" name="checkSMTP">
-
-
-                <div class="row">
-                    <div class="col-md-12">
-                        <div class="form-group">
-                            <div class="custom-control mb-3">
-                                <label for="method">Your E-Mail method</label>
-                                <input id="method" name="method"
-                                       type="text" required
-                                       value="smtp" class="form-control">
-
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <div class="custom-control mb-3">
-                                <label for="host">Your Mailer-Host</label>
-                                <input id="host" name="host" type="text"
-                                       required
-                                       value="smtp.google.com" class="form-control">
-                            </div>
-                        </div>
-
-                        <div class="form-group">
-                            <div class="custom-control mb-3">
-                                <label for="port">Your Mail Port</label>
-                                <input id="port" name="port" type="port"
-                                       required
-                                       value="567" class="form-control">
-                            </div>
-                        </div>
-
-                        <div class="form-group">
-                            <div class="custom-control mb-3">
-                                <label for="user">Your Mail User</label>
-                                <input id="user" name="user" type="text"
-                                       required
-                                       value="info@mydomain.com" class="form-control">
-                            </div>
-                        </div>
-
-
-                        <div class="form-group">
-                            <div class="custom-control mb-3">
-                                <label for="pass">Your Mail-User Password</label>
-                                <input id="pass" name="pass" type="password"
-                                       required
-                                       value="" class="form-control">
-                            </div>
-                        </div>
-
-                        <div class="form-group">
-                            <div class="custom-control mb-3">
-                                <label for="encryption">Your Mail encryption method</label>
-                                <input id="encryption" name="encryption" type="text"
-                                       required
-                                       value="tls" class="form-control">
-                            </div>
-                        </div>
+    </div>
+
+    <?php
+}
+if (isset($_GET['step']) && $_GET['step'] == 4) {
+    echo $cardheader; ?>
+    <p class="login-box-msg">Lets get your E-Mails going! </p>
+    <p class="login-box-msg">This might take a few seconds when submitted! </p>
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='notok'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <form method="POST" enctype="multipart/form-data" class="mb-3"
+
+          action="/install/forms.php" name="checkSMTP">
 
 
-                    </div>
 
 
-                    <button class="btn btn-primary" name="checkSMTP">Submit</button>
-            </form>
+        <div class="row">
+            <div class="col-md-12">
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="method">Your E-Mail method</label>
+                        <input id="method" name="method"
+                               type="text" required
+                               value="smtp" class="form-control">
 
 
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="host">Your Mailer-Host</label>
+                        <input id="host" name="host" type="text"
+                               required
+                               value="smtp.google.com" class="form-control">
+                    </div>
                 </div>
                 </div>
 
 
-                <a href="?step=5"><button class="btn btn-warning">Skip this step for now</button></a>
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="port">Your Mail Port</label>
+                        <input id="port" name="port" type="port"
+                               required
+                               value="567" class="form-control">
+                    </div>
                 </div>
                 </div>
 
 
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="user">Your Mail User</label>
+                        <input id="user" name="user" type="text"
+                               required
+                               value="info@mydomain.com" class="form-control">
+                    </div>
                 </div>
                 </div>
-                <?php
-            }
-
-                if (isset($_GET['step']) && $_GET['step'] == 5) {
-                    echo $cardheader; ?>
-
-                <p class="login-box-msg">Almost done! </p>
-                <p class="login-box-msg">Lets get some info about your Pterodactyl Installation!</p>
-
-
-                <?php if (isset($_GET['message'])) {
-                        echo "<p class='notok'>".$_GET['message'].'</p>';
-                    } ?>
-
-                <form method="POST" enctype="multipart/form-data" class="mb-3"
-
-                      action="/install/forms.php" name="checkPtero">
-
-
-                    <div class="row">
-                        <div class="col-md-12">
-                            <div class="form-group">
-                                <div class="custom-control mb-3">
-
-                                    <label for="url">Pterodactyl URL</label>
-                                    <input id="url" name="url"
-                                           type="text" required
-                                           value="https://ptero.example.com" class="form-control">
-                                </div>
-                            </div>
-                            <div class="form-group">
-                                <div class="custom-control mb-3">
-                                    <label for="key">Pterodactyl API-Key (found here: https://your.ptero.com/admin/api)</label>
-                                    <input id="key" name="key" type="text"
-                                           required
-                                           value="" class="form-control"
-                                           placeholder="The Key needs ALL read&write Permissions!">
-                                </div>
-                            </div>
-                            <div class="form-group">
-                                <div class="custom-control mb-3">
-                                    <label for="clientkey">Pterodactyl Admin-User API-Key (https://your.ptero.com/account/api)</label>
-                                    <input id="clientkey" name="clientkey" type="text"
-                                           required
-                                           value="" class="form-control"
-                                           placeholder="Your Account needs to be an Admin!">
-                                </div>
-                            </div>
-
-
-                        </div>
-
-                        <button  class="btn btn-primary" name="checkPtero">Submit</button>
+
+
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="pass">Your Mail-User Password</label>
+                        <input id="pass" name="pass" type="password"
+                               required
+                               value="" class="form-control">
                     </div>
                     </div>
-                </form>
+                </div>
+
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="encryption">Your Mail encryption method</label>
+                        <input id="encryption" name="encryption" type="text"
+                               required
+                               value="tls" class="form-control">
                     </div>
                     </div>
+                </div>
+
+            </div>
+
+            <button class="btn btn-primary" name="checkSMTP">Submit</button>
+    </form>
+
+    </div>
+
+    <a href="?step=5">
+        <button class="btn btn-warning">Skip this step for now</button>
+    </a>
+    </div>
 
 
+    </div>
+    <?php
+}
 
 
+if (isset($_GET['step']) && $_GET['step'] == 5) {
+    echo $cardheader; ?>
+
+    <p class="login-box-msg">Almost done! </p>
+    <p class="login-box-msg">Lets get some info about your Pterodactyl Installation!</p>
+
+
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='notok'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <form method="POST" enctype="multipart/form-data" class="mb-3"
+
+          action="/install/forms.php" name="checkPtero">
+
+
+        <div class="row">
+            <div class="col-md-12">
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+
+                        <label for="url">Pterodactyl URL</label>
+                        <input id="url" name="url"
+                               type="text" required
+                               value="https://ptero.example.com" class="form-control">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="key">Pterodactyl API-Key (found here: https://your.ptero.com/admin/api)</label>
+                        <input id="key" name="key" type="text"
+                               required
+                               value="" class="form-control"
+                               placeholder="The Key needs ALL read&write Permissions!">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="custom-control mb-3">
+                        <label for="clientkey">Pterodactyl Admin-User API-Key
+                            (https://your.ptero.com/account/api)</label>
+                        <input id="clientkey" name="clientkey" type="text"
+                               required
+                               value="" class="form-control"
+                               placeholder="Your Account needs to be an Admin!">
                     </div>
                     </div>
+                </div>
+
+
+            </div>
+
+            <button class="btn btn-primary" name="checkPtero">Submit</button>
+        </div>
+    </form>
+    </div>
+
+
+    </div>
+
+    <?php
+}
+
+if (isset($_GET['step']) && $_GET['step'] == 6) {
+    echo $cardheader; ?>
+    <p class="login-box-msg">Lets create yourself!</p>
+    <p class="login-box-msg">We're making the first Admin user</p>
+    <?php if (isset($_GET['message'])) {
+        echo "<p class='notok'>" . $_GET['message'] . '</p>';
+    } ?>
+
+    <form method="POST" enctype="multipart/form-data" class="mb-3"
+          action="/install/forms.php" name="createUser">
+
+        <div class="form-group">
+            <div class="custom-control mb-3">
+                <label for="pteroID">Your Pterodactyl User-ID (found in the users-list on your pterodactyl
+                    dashboard)</label>
+                <input id="pteroID" name="pteroID" type="text"
+                       required
+                       value="1" class="form-control">
+            </div>
+        </div>
+
+        <div class="form-group">
+            <div class="custom-control mb-3">
+                <label for="pass">Password (this will be your new pterodactyl password aswell!)</label>
+                <input id="pass" name="pass" type="password"
+                       required
+                       value="" minlength="8" class="form-control">
+            </div>
+        </div>
+        <div class="form-group">
+            <div class="custom-control mb-3">
+                <label for="repass">Retype Password</label>
+                <input id="repass" name="repass" type="password"
+                       required
+                       value="" minlength="8" class="form-control">
+            </div>
+        </div>
+
+        </div>
+
+        <button class="btn btn-primary" name="createUser">Submit</button>
+        </div>
+    </form>
+    </div>
+
+
+    </div>
+
+    <?php
+}
+if (isset($_GET['step']) && $_GET['step'] == 7) {
+    $lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
+    fwrite($lockfile, 'locked');
+    fclose($lockfile);
+
+    echo $cardheader; ?>
+    <p class="login-box-msg">All done!</p>
+    <p class="login-box-msg">You may navigate to your Dashboard now and log in!</p>
+    <a href="<?php echo getenv('APP_URL'); ?>">
+        <button class="btn btn-success">Lets go!</button>
+    </a>
+    </div>
+
+
+    </div>
+    <?php
+}
+?>
+
 
 
-                    <?php
-                }
-
-                    if (isset($_GET['step']) && $_GET['step'] == 6) {
-                        echo $cardheader; ?>
-                    <p class="login-box-msg">Lets create yourself!</p>
-                    <p class="login-box-msg">We're making the first Admin user</p>
-                    <?php if (isset($_GET['message'])) {
-                            echo "<p class='notok'>".$_GET['message'].'</p>';
-                        } ?>
-
-                    <form method="POST" enctype="multipart/form-data" class="mb-3"
-                          action="/install/forms.php" name="createUser">
-
-                        <div class="form-group">
-                            <div class="custom-control mb-3">
-                                <label for="pteroID">Your Pterodactyl User-ID (found in the users-list on your pterodactyl dashboard)</label>
-                                <input id="pteroID" name="pteroID" type="text"
-                                       required
-                                       value="1" class="form-control">
-                            </div>
-                        </div>
-
-                                <div class="form-group">
-                                    <div class="custom-control mb-3">
-                                        <label for="pass">Password (this will be your new pterodactyl password aswell!)</label>
-                                        <input id="pass" name="pass" type="password"
-                                               required
-                                               value="" minlength="8" class="form-control">
-                                    </div>
-                                </div>
-                                <div class="form-group">
-                                    <div class="custom-control mb-3">
-                                        <label for="repass">Retype Password</label>
-                                        <input id="repass" name="repass" type="password"
-                                               required
-                                               value="" minlength="8" class="form-control">
-                                    </div>
-                                </div>
-
-                            </div>
-
-                            <button class="btn btn-primary" name="createUser">Submit</button>
-                        </div>
-                    </form>
-                        </div>
-
-
-                        </div>
-
-                        <?php
-                    }
-                        if (isset($_GET['step']) && $_GET['step'] == 7) {
-                            $lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
-                            fwrite($lockfile, 'locked');
-                            fclose($lockfile);
-
-                            echo $cardheader; ?>
-                            <p class="login-box-msg">All done!</p>
-                            <p class="login-box-msg">You may navigate to your Dashboard now and log in!</p>
-                            <a href="<?php echo getEnvironmentValue('APP_URL'); ?>">
-                                <button class="btn btn-success">Lets go!</button>
-                            </a>
-                            </div>
-
-
-                            </div>
-                            <?php
-                        }
-                        ?>
-
-
-                        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
-                                integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
-                                crossorigin="anonymous"></script>
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
+        integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
+        crossorigin="anonymous"></script>
 </body>
 </body>
 </html>
 </html>

+ 52 - 30
themes/default/views/admin/servers/index.blade.php

@@ -6,12 +6,13 @@
         <div class="container-fluid">
         <div class="container-fluid">
             <div class="row mb-2">
             <div class="row mb-2">
                 <div class="col-sm-6">
                 <div class="col-sm-6">
-                    <h1>{{__('Servers')}}</h1>
+                    <h1>{{ __('Servers') }}</h1>
                 </div>
                 </div>
                 <div class="col-sm-6">
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">
                     <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
-                        <li class="breadcrumb-item"><a class="text-muted" href="{{route('admin.servers.index')}}">{{__('Servers')}}</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                href="{{ route('admin.servers.index') }}">{{ __('Servers') }}</a></li>
                     </ol>
                     </ol>
                 </div>
                 </div>
             </div>
             </div>
@@ -27,25 +28,25 @@
                 <div class="card-header">
                 <div class="card-header">
                     <div class="d-flex justify-content-between">
                     <div class="d-flex justify-content-between">
                         <div class="card-title ">
                         <div class="card-title ">
-                            <span><i class="fas fa-server mr-2"></i>{{__('Servers')}}</span>
+                            <span><i class="fas fa-server mr-2"></i>{{ __('Servers') }}</span>
                         </div>
                         </div>
-                        <a href="{{route('admin.servers.sync')}}" class="btn btn-primary btn-sm"><i
-                                class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
+                        <a href="{{ route('admin.servers.sync') }}" class="btn btn-primary btn-sm"><i
+                                class="fas fa-sync mr-2"></i>{{ __('Sync') }}</a>
                     </div>
                     </div>
                 </div>
                 </div>
                 <div class="card-body table-responsive">
                 <div class="card-body table-responsive">
                     <table id="datatable" class="table table-striped">
                     <table id="datatable" class="table table-striped">
                         <thead>
                         <thead>
-                        <tr>
-                            <th width="20">{{ __('Status') }}</th>
-                            <th>{{__('Name')}}</th>
-                            <th>{{__('User')}}</th>
-                            <th>{{__('Server id')}}</th>
-                            <th>{{__('Config')}}</th>
-                            <th>{{__('Suspended at')}}</th>
-                            <th>{{__('Created at')}}</th>
-                            <th>{{ __('Actions') }}</th>
-                        </tr>
+                            <tr>
+                                <th width="20">{{ __('Status') }}</th>
+                                <th>{{ __('Name') }}</th>
+                                <th>{{ __('User') }}</th>
+                                <th>{{ __('Server id') }}</th>
+                                <th>{{ __('Product') }}</th>
+                                <th>{{ __('Suspended at') }}</th>
+                                <th>{{ __('Created at') }}</th>
+                                <th>{{ __('Actions') }}</th>
+                            </tr>
                         </thead>
                         </thead>
                         <tbody>
                         <tbody>
                         </tbody>
                         </tbody>
@@ -61,10 +62,10 @@
 
 
 <script>
 <script>
     function submitResult() {
     function submitResult() {
-        return confirm("{{__('Are you sure you wish to delete?')}}") !== false;
+        return confirm("{{ __('Are you sure you wish to delete?') }}") !== false;
     }
     }
 
 
-    document.addEventListener("DOMContentLoaded", function () {
+    document.addEventListener("DOMContentLoaded", function() {
         $('#datatable').DataTable({
         $('#datatable').DataTable({
             language: {
             language: {
                 url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{ $locale_datatables }}.json'
                 url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{ $locale_datatables }}.json'
@@ -72,19 +73,40 @@
             processing: true,
             processing: true,
             serverSide: true,
             serverSide: true,
             stateSave: true,
             stateSave: true,
-            ajax: "{{route('admin.servers.datatable')}}{{$filter ?? ''}}",
-            order: [[ 5, "desc" ]],
-            columns: [
-                {data: 'status' , name : 'servers.suspended'},
-                {data: 'name'},
-                {data: 'user' , name : 'user.name'},
-                {data: 'identifier'},
-                {data: 'resources' , name : 'product.name'},
-                {data: 'suspended'},
-                {data: 'created_at'},
-                {data: 'actions' , sortable : false},
+            ajax: "{{ route('admin.servers.datatable') }}{{ $filter ?? '' }}",
+            order: [
+                [5, "desc"]
             ],
             ],
-            fnDrawCallback: function( oSettings ) {
+            columns: [{
+                    data: 'status',
+                    name: 'servers.suspended'
+                },
+                {
+                    data: 'name'
+                },
+                {
+                    data: 'user',
+                    name: 'user.name'
+                },
+                {
+                    data: 'identifier'
+                },
+                {
+                    data: 'product.name',
+                    sortable: false
+                },
+                {
+                    data: 'suspended'
+                },
+                {
+                    data: 'created_at'
+                },
+                {
+                    data: 'actions',
+                    sortable: false
+                },
+            ],
+            fnDrawCallback: function(oSettings) {
                 $('[data-toggle="popover"]').popover();
                 $('[data-toggle="popover"]').popover();
             }
             }
         });
         });

+ 129 - 102
themes/default/views/admin/users/show.blade.php

@@ -6,14 +6,14 @@
         <div class="container-fluid">
         <div class="container-fluid">
             <div class="row mb-2">
             <div class="row mb-2">
                 <div class="col-sm-6">
                 <div class="col-sm-6">
-                    <h1>{{__('Users')}}</h1>
+                    <h1>{{ __('Users') }}</h1>
                 </div>
                 </div>
                 <div class="col-sm-6">
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">
                     <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
-                        <li class="breadcrumb-item"><a href="{{route('admin.users.index')}}">{{__('Users')}}</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('admin.users.index') }}">{{ __('Users') }}</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
                         <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{route('admin.users.show' , $user->id)}}">{{__('Show')}}</a>
+                                href="{{ route('admin.users.show', $user->id) }}">{{ __('Show') }}</a>
                         </li>
                         </li>
                     </ol>
                     </ol>
                 </div>
                 </div>
@@ -26,18 +26,18 @@
     <section class="content">
     <section class="content">
         <div class="container-fluid">
         <div class="container-fluid">
 
 
-            @if($user->discordUser)
+            @if ($user->discordUser)
                 <div class="row">
                 <div class="row">
                     <div class="col-lg-4 col-md-6">
                     <div class="col-lg-4 col-md-6">
                         <div class="small-box bg-dark">
                         <div class="small-box bg-dark">
                             <div class="d-flex justify-content-between">
                             <div class="d-flex justify-content-between">
                                 <div class="p-3">
                                 <div class="p-3">
-                                    <h3>{{$user->discordUser->username}} <sup>{{$user->discordUser->locale}}</sup></h3>
-                                    <p>{{$user->discordUser->id}}
+                                    <h3>{{ $user->discordUser->username }} <sup>{{ $user->discordUser->locale }}</sup></h3>
+                                    <p>{{ $user->discordUser->id }}
                                     </p>
                                     </p>
                                 </div>
                                 </div>
                                 <div class="p-3"><img width="100px" height="100px" class="rounded-circle"
                                 <div class="p-3"><img width="100px" height="100px" class="rounded-circle"
-                                                      src="{{$user->discordUser->getAvatar()}}" alt="avatar"></div>
+                                        src="{{ $user->discordUser->getAvatar() }}" alt="avatar"></div>
                             </div>
                             </div>
                             <div class="small-box-footer">
                             <div class="small-box-footer">
                                 <i class="fab fa-discord mr-1"></i>Discord
                                 <i class="fab fa-discord mr-1"></i>Discord
@@ -50,7 +50,7 @@
 
 
             <div class="card">
             <div class="card">
                 <div class="card-header">
                 <div class="card-header">
-                    <h5 class="card-title"><i class="fas fa-users mr-2"></i>{{__('Users')}}</h5>
+                    <h5 class="card-title"><i class="fas fa-users mr-2"></i>{{ __('Users') }}</h5>
                 </div>
                 </div>
                 <div class="card-body">
                 <div class="card-body">
                     <div class="row">
                     <div class="row">
@@ -58,12 +58,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('ID')}}</label>
+                                    <label>{{ __('ID') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$user->id}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->id }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -71,13 +71,21 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Role')}}</label>
+                                    <label>{{ __('Role') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;"
-                                             class="d-inline-block text-truncate badge {{$user->role == 'admin' || $user->role == 'mod' ? 'badge-info' : 'badge-secondary'}}">
-                                           {{$user->role}}
-                                       </span>
+                                    <span style="max-width: 250px;"
+                                        class="d-inline-block text-truncate badge
+                                        @if ($user->role == 'admin') badge-danger
+                                        @elseif ($user->role == 'moderator')
+                                            badge-info
+                                        @elseif ($user->role == 'client')
+                                            badge-success
+                                        @else
+                                            badge-secondary @endif
+                                        ">
+                                        {{ $user->role }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -85,12 +93,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Pterodactyl ID')}}</label>
+                                    <label>{{ __('Pterodactyl ID') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$user->pterodactyl_id}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->pterodactyl_id }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -98,12 +106,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Email')}}</label>
+                                    <label>{{ __('Email') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$user->email}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->email }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -112,12 +120,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Server limit')}}</label>
+                                    <label>{{ __('Server limit') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$user->Servers()->count()}} / {{$user->server_limit}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->Servers()->count() }} / {{ $user->server_limit }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -125,12 +133,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Name')}}</label>
+                                    <label>{{ __('Name') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$user->name}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->name }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -138,12 +146,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Verified')}} {{__('Email')}}</label>
+                                    <label>{{ __('Verified') }} {{ __('Email') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$user->email_verified_at ? 'True' : 'False'}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->email_verified_at ? 'True' : 'False' }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -154,9 +162,9 @@
                                     <label>{{ $credits_display_name }}</label>
                                     <label>{{ $credits_display_name }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           <i class="fas fa-coins mr-2"></i>{{$user->Credits()}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        <i class="fas fa-coins mr-2"></i>{{ $user->Credits() }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -164,12 +172,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Verified')}} {{__('Discord')}}</label>
+                                    <label>{{ __('Verified') }} {{ __('Discord') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$user->discordUser ? 'True' : 'False'}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->discordUser ? 'True' : 'False' }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -177,12 +185,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Usage')}}</label>
+                                    <label>{{ __('Usage') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                          <i class="fas fa-coins mr-2"></i>{{$user->CreditUsage()}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        <i class="fas fa-coins mr-2"></i>{{ $user->CreditUsage() }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -191,12 +199,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('IP')}}</label>
+                                    <label>{{ __('IP') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$user->ip}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->ip }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -204,12 +212,12 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Created at')}}</label>
+                                    <label>{{ __('Created at') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$user->created_at->diffForHumans()}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $user->created_at->diffForHumans() }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -220,17 +228,16 @@
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>{{__('Last seen')}}</label>
+                                    <label>{{ __('Last seen') }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           @if($user->last_seen)
-                                               {{$user->last_seen->diffForHumans()}}
-                                           @else
-                                               <small
-                                                   class="text-muted">Null</small>
-                                           @endif
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        @if ($user->last_seen)
+                                            {{ $user->last_seen->diffForHumans() }}
+                                        @else
+                                            <small class="text-muted">Null</small>
+                                        @endif
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -243,21 +250,21 @@
 
 
             <div class="card">
             <div class="card">
                 <div class="card-header">
                 <div class="card-header">
-                    <h5 class="card-title"><i class="fas fa-server mr-2"></i>{{__('Servers')}}</h5>
+                    <h5 class="card-title"><i class="fas fa-server mr-2"></i>{{ __('Servers') }}</h5>
                 </div>
                 </div>
                 <div class="card-body table-responsive">
                 <div class="card-body table-responsive">
                     <table id="datatable" class="table table-striped">
                     <table id="datatable" class="table table-striped">
                         <thead>
                         <thead>
-                        <tr>
-                            <th width="20"></th>
-                            <th>{{__('Name')}}</th>
-                            <th>{{__('User')}}</th>
-                            <th>{{__('Server id')}}</th>
-                            <th>{{__('Config')}}</th>
-                            <th>{{__('Suspended at')}}</th>
-                            <th>{{__('Created at')}}</th>
-                            <th></th>
-                        </tr>
+                            <tr>
+                                <th width="20"></th>
+                                <th>{{ __('Name') }}</th>
+                                <th>{{ __('User') }}</th>
+                                <th>{{ __('Server id') }}</th>
+                                <th>{{ __('Config') }}</th>
+                                <th>{{ __('Suspended at') }}</th>
+                                <th>{{ __('Created at') }}</th>
+                                <th></th>
+                            </tr>
                         </thead>
                         </thead>
                         <tbody>
                         <tbody>
                         </tbody>
                         </tbody>
@@ -267,28 +274,28 @@
             </div>
             </div>
             <div class="card">
             <div class="card">
                 <div class="card-header">
                 <div class="card-header">
-                    <h5 class="card-title"><i class="fas fa-user-check mr-2"></i>{{__('Referals')}}
-                        ({{__("referral-code")}}: {{$user->referral_code}})</h5>
+                    <h5 class="card-title"><i class="fas fa-user-check mr-2"></i>{{ __('Referals') }}
+                        ({{ __('referral-code') }}: {{ $user->referral_code }})</h5>
                 </div>
                 </div>
                 <div class="card-body table-responsive">
                 <div class="card-body table-responsive">
 
 
 
 
-                    @foreach($referrals as $referral)
+                    @foreach ($referrals as $referral)
                         <div class="col-lg-6">
                         <div class="col-lg-6">
                             <div class="row">
                             <div class="row">
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                    <label>User ID: {{$referral->id}}</label>
+                                    <label>User ID: {{ $referral->id }}</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           <i class="fas fa-user-check mr-2"></i><a
-                                               href="{{route("admin.users.show",$referral->id)}}">{{$referral->name}}</a>
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        <i class="fas fa-user-check mr-2"></i><a
+                                            href="{{ route('admin.users.show', $referral->id) }}">{{ $referral->name }}</a>
+                                    </span>
                                 </div>
                                 </div>
                                 <div class="col-lg-4">
                                 <div class="col-lg-4">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           <i class="fas fa-clock mr-2"></i>{{$referral->created_at->diffForHumans()}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        <i class="fas fa-clock mr-2"></i>{{ $referral->created_at->diffForHumans() }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -302,11 +309,10 @@
         </div>
         </div>
     </section>
     </section>
     <!-- END CONTENT -->
     <!-- END CONTENT -->
-
 @endsection
 @endsection
 
 
 <script>
 <script>
-    document.addEventListener("DOMContentLoaded", function () {
+    document.addEventListener("DOMContentLoaded", function() {
         $('#datatable').DataTable({
         $('#datatable').DataTable({
             language: {
             language: {
                 url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{ $locale_datatables }}.json'
                 url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{ $locale_datatables }}.json'
@@ -314,19 +320,40 @@
             processing: true,
             processing: true,
             serverSide: true,
             serverSide: true,
             stateSave: true,
             stateSave: true,
-            ajax: "{{route('admin.servers.datatable')}}?user={{ $user->id }}",
-            order: [[ 5, "desc" ]],
-            columns: [
-                {data: 'status' , name : 'servers.suspended'},
-                {data: 'name'},
-                {data: 'user' , name : 'user.name'},
-                {data: 'identifier'},
-                {data: 'resources' , name : 'product.name'},
-                {data: 'suspended'},
-                {data: 'created_at'},
-                {data: 'actions' , sortable : false},
+            ajax: "{{ route('admin.servers.datatable') }}?user={{ $user->id }}",
+            order: [
+                [5, "desc"]
+            ],
+            columns: [{
+                    data: 'status',
+                    name: 'servers.suspended'
+                },
+                {
+                    data: 'name'
+                },
+                {
+                    data: 'user',
+                    name: 'user.name'
+                },
+                {
+                    data: 'identifier'
+                },
+                {
+                    data: 'resources',
+                    name: 'product.name'
+                },
+                {
+                    data: 'suspended'
+                },
+                {
+                    data: 'created_at'
+                },
+                {
+                    data: 'actions',
+                    sortable: false
+                },
             ],
             ],
-            fnDrawCallback: function( oSettings ) {
+            fnDrawCallback: function(oSettings) {
                 $('[data-toggle="popover"]').popover();
                 $('[data-toggle="popover"]').popover();
             }
             }
         });
         });