Browse Source

Merge pull request #589 from ControlPanel-gg/development

V. 0.8.3.1 Small Fixes
Dennis 2 years ago
parent
commit
39c86257a9

+ 1 - 0
.gitignore

@@ -15,6 +15,7 @@ Homestead.json
 Homestead.yaml
 npm-debug.log
 yarn-error.log
+yarn.lock
 .gitignore
 .env.dev
 .env.testing

+ 3 - 1
app/Classes/Settings/System.php

@@ -45,7 +45,7 @@ public function checkPteroClientkey(){
             "per-page-limit" => "required|min:0|integer",
             "pterodactyl-admin-api-key" => "required|string",
             "enable-upgrades" => "string",
-
+            "enable-disable-servers" => "string",
         ]);
 
         $validator->after(function ($validator) use ($request) {
@@ -85,6 +85,8 @@ public function checkPteroClientkey(){
             "SETTINGS::SYSTEM:ENABLE_LOGIN_LOGO" => "enable-login-logo",
             "SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN" => "pterodactyl-admin-api-key",
             "SETTINGS::SYSTEM:ENABLE_UPGRADE" => "enable-upgrade",
+            "SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS" => "enable-disable-servers",
+            "SETTINGS::SYSTEM:CREATION_OF_NEW_USERS" => "enable-disable-new-users",
         ];
 
 

+ 95 - 89
app/Http/Controllers/Admin/OverViewController.php

@@ -22,103 +22,108 @@ class OverViewController extends Controller
 
     public function index()
     {
-        $counters = Cache::remember('counters', self::TTL, function () {
-            $output = collect();
-            //Set basic variables in the collection
-            $output->put('users', User::query()->count());
-            $output->put('credits', number_format(User::query()->where("role","!=","admin")->sum('credits'), 2, '.', ''));
-            $output->put('payments', Payment::query()->count());
-            $output->put('eggs', Egg::query()->count());
-            $output->put('nests', Nest::query()->count());
-            $output->put('locations', Location::query()->count());
-
-            //Prepare for counting
-            $output->put('servers', collect());
-            $output['servers']->active = 0;
-            $output['servers']->total = 0;
-            $output->put('earnings', collect());
-            $output['earnings']->active = 0;
-            $output['earnings']->total = 0;
-            $output->put('totalUsagePercent', 0);
-
-            //Prepare subCollection 'payments'
-            $output->put('payments', collect());
-            //Get and save payments from last 2 months for later filtering and looping
-            $payments = Payment::query()->where('created_at', '>=', Carbon::today()->startOfMonth()->subMonth())->where('status', 'paid')->get();
-            //Prepare collections and set a few variables
-            $output['payments']->put('thisMonth', collect());
-            $output['payments']->put('lastMonth', collect());
-            $output['payments']['thisMonth']->timeStart = Carbon::today()->startOfMonth()->toDateString();
-            $output['payments']['thisMonth']->timeEnd = Carbon::today()->toDateString();
-            $output['payments']['lastMonth']->timeStart = Carbon::today()->startOfMonth()->subMonth()->toDateString();
-            $output['payments']['lastMonth']->timeEnd = Carbon::today()->endOfMonth()->subMonth()->toDateString();
-            
-            //Fill out variables for each currency separately
-            foreach($payments->where('created_at', '>=', Carbon::today()->startOfMonth()) as $payment){
-                $paymentCurrency = $payment->currency_code;
-                if(!isset($output['payments']['thisMonth'][$paymentCurrency])){
-                    $output['payments']['thisMonth']->put($paymentCurrency, collect());
-                    $output['payments']['thisMonth'][$paymentCurrency]->total = 0;
-                    $output['payments']['thisMonth'][$paymentCurrency]->count = 0;
-                }
-                $output['payments']['thisMonth'][$paymentCurrency]->total += $payment->total_price;
-                $output['payments']['thisMonth'][$paymentCurrency]->count ++;
+        //Get counters
+        $counters = collect();
+        //Set basic variables in the collection
+        $counters->put('users', User::query()->count());
+        $counters->put('credits', number_format(User::query()->where("role","!=","admin")->sum('credits'), 2, '.', ''));
+        $counters->put('payments', Payment::query()->count());
+        $counters->put('eggs', Egg::query()->count());
+        $counters->put('nests', Nest::query()->count());
+        $counters->put('locations', Location::query()->count());
+
+        //Prepare for counting
+        $counters->put('servers', collect());
+        $counters['servers']->active = 0;
+        $counters['servers']->total = 0;
+        $counters->put('earnings', collect());
+        $counters['earnings']->active = 0;
+        $counters['earnings']->total = 0;
+        $counters->put('totalUsagePercent', 0);
+
+        //Prepare subCollection 'payments'
+        $counters->put('payments', collect());
+        //Get and save payments from last 2 months for later filtering and looping
+        $payments = Payment::query()->where('created_at', '>=', Carbon::today()->startOfMonth()->subMonth())->where('status', 'paid')->get();
+        //Prepare collections and set a few variables
+        $counters['payments']->put('thisMonth', collect());
+        $counters['payments']->put('lastMonth', collect());
+        $counters['payments']['thisMonth']->timeStart = Carbon::today()->startOfMonth()->toDateString();
+        $counters['payments']['thisMonth']->timeEnd = Carbon::today()->toDateString();
+        $counters['payments']['lastMonth']->timeStart = Carbon::today()->startOfMonth()->subMonth()->toDateString();
+        $counters['payments']['lastMonth']->timeEnd = Carbon::today()->endOfMonth()->subMonth()->toDateString();
+        
+        //Fill out variables for each currency separately
+        foreach($payments->where('created_at', '>=', Carbon::today()->startOfMonth()) as $payment){
+            $paymentCurrency = $payment->currency_code;
+            if(!isset($counters['payments']['thisMonth'][$paymentCurrency])){
+                $counters['payments']['thisMonth']->put($paymentCurrency, collect());
+                $counters['payments']['thisMonth'][$paymentCurrency]->total = 0;
+                $counters['payments']['thisMonth'][$paymentCurrency]->count = 0;
             }
-            foreach($payments->where('created_at', '<', Carbon::today()->startOfMonth()) as $payment){
-                $paymentCurrency = $payment->currency_code;
-                if(!isset($output['payments']['lastMonth'][$paymentCurrency])){
-                    $output['payments']['lastMonth']->put($paymentCurrency, collect());
-                    $output['payments']['lastMonth'][$paymentCurrency]->total = 0;
-                    $output['payments']['lastMonth'][$paymentCurrency]->count = 0;
-                }
-                $output['payments']['lastMonth'][$paymentCurrency]->total += $payment->total_price;
-                $output['payments']['lastMonth'][$paymentCurrency]->count ++;
+            $counters['payments']['thisMonth'][$paymentCurrency]->total += $payment->total_price;
+            $counters['payments']['thisMonth'][$paymentCurrency]->count ++;
+        }
+        foreach($payments->where('created_at', '<', Carbon::today()->startOfMonth()) as $payment){
+            $paymentCurrency = $payment->currency_code;
+            if(!isset($counters['payments']['lastMonth'][$paymentCurrency])){
+                $counters['payments']['lastMonth']->put($paymentCurrency, collect());
+                $counters['payments']['lastMonth'][$paymentCurrency]->total = 0;
+                $counters['payments']['lastMonth'][$paymentCurrency]->count = 0;
             }
-            $output['payments']->total = Payment::query()->count();
-            
-            return $output;
-        });
+            $counters['payments']['lastMonth'][$paymentCurrency]->total += $payment->total_price;
+            $counters['payments']['lastMonth'][$paymentCurrency]->count ++;
+        }
+        $counters['payments']->total = Payment::query()->count();
 
         $lastEgg = Egg::query()->latest('updated_at')->first();
         $syncLastUpdate = $lastEgg ? $lastEgg->updated_at->isoFormat('LLL') : __('unknown');
         
-        $nodes = Cache::remember('nodes', self::TTL, function() use($counters){
-            $output = collect();
-            foreach($nodes = Node::query()->get() as $node){ //gets all node information and prepares the structure
-                $nodeId = $node['id'];
-                $output->put($nodeId, collect());
-                $output[$nodeId]->name = $node['name'];
-                $node = Pterodactyl::getNode($nodeId);
-                $output[$nodeId]->usagePercent = round(max($node['allocated_resources']['memory']/($node['memory']*($node['memory_overallocate']+100)/100), $node['allocated_resources']['disk']/($node['disk']*($node['disk_overallocate']+100)/100))*100, 2);
-                $counters['totalUsagePercent'] += $output[$nodeId]->usagePercent;
-
-                $output[$nodeId]->totalServers = 0;
-                $output[$nodeId]->activeServers = 0;
-                $output[$nodeId]->totalEarnings = 0;
-                $output[$nodeId]->activeEarnings = 0;
-            }
-            $counters['totalUsagePercent'] = ($nodes->count())?round($counters['totalUsagePercent']/$nodes->count(), 2):0;
-
-            foreach(Pterodactyl::getServers() as $server){ //gets all servers from Pterodactyl and calculates total of credit usage for each node separately + total
-                $nodeId = $server['attributes']['node'];
-                
-                if($CPServer = Server::query()->where('pterodactyl_id', $server['attributes']['id'])->first()){
-                    $prize = Product::query()->where('id', $CPServer->product_id)->first()->price;
-                    if (!$CPServer->suspended){
-                        $counters['earnings']->active += $prize;
-                        $counters['servers']->active ++;
-                        $output[$nodeId]->activeEarnings += $prize;
-                        $output[$nodeId]->activeServers ++;
-                    }
-                    $counters['earnings']->total += $prize;
-                    $counters['servers']->total ++;
-                    $output[$nodeId]->totalEarnings += $prize;
-                    $output[$nodeId]->totalServers ++;
+
+
+        //Get node information and prepare collection
+        $pteroNodeIds = [];
+        foreach(Pterodactyl::getNodes() as $pteroNode){
+            array_push($pteroNodeIds, $pteroNode['attributes']['id']);
+        }
+        $nodes = collect();
+        foreach($DBnodes = Node::query()->get() as $DBnode){ //gets all node information and prepares the structure
+            $nodeId = $DBnode['id'];
+            if(!in_array($nodeId, $pteroNodeIds)) continue; //Check if node exists on pterodactyl too, if not, skip
+            $nodes->put($nodeId, collect());
+            $nodes[$nodeId]->name = $DBnode['name'];
+            $pteroNode = Pterodactyl::getNode($nodeId);
+            $nodes[$nodeId]->usagePercent = round(max($pteroNode['allocated_resources']['memory']/($pteroNode['memory']*($pteroNode['memory_overallocate']+100)/100), $pteroNode['allocated_resources']['disk']/($pteroNode['disk']*($pteroNode['disk_overallocate']+100)/100))*100, 2);
+            $counters['totalUsagePercent'] += $nodes[$nodeId]->usagePercent;
+
+            $nodes[$nodeId]->totalServers = 0;
+            $nodes[$nodeId]->activeServers = 0;
+            $nodes[$nodeId]->totalEarnings = 0;
+            $nodes[$nodeId]->activeEarnings = 0;
+        }
+        $counters['totalUsagePercent'] = ($DBnodes->count())?round($counters['totalUsagePercent']/$DBnodes->count(), 2):0;
+
+        foreach(Pterodactyl::getServers() as $server){ //gets all servers from Pterodactyl and calculates total of credit usage for each node separately + total
+            $nodeId = $server['attributes']['node'];
+            
+            if($CPServer = Server::query()->where('pterodactyl_id', $server['attributes']['id'])->first()){
+                $price = Product::query()->where('id', $CPServer->product_id)->first()->price;
+                if (!$CPServer->suspended){
+                    $counters['earnings']->active += $price;
+                    $counters['servers']->active ++;
+                    $nodes[$nodeId]->activeEarnings += $price;
+                    $nodes[$nodeId]->activeServers ++;
                 }
+                $counters['earnings']->total += $price;
+                $counters['servers']->total ++;
+                $nodes[$nodeId]->totalEarnings += $price;
+                $nodes[$nodeId]->totalServers ++;
             }
-            return $output;
-        });
+        }
+
 
+
+        //Get latest tickets
         $tickets = Cache::remember('tickets', self::TTL, function(){
             $output = collect();
             foreach(Ticket::query()->latest()->take(3)->get() as $ticket){
@@ -146,11 +151,12 @@ class OverViewController extends Controller
             }
             return $output;
         });
-        //dd($counters);
+
         return view('admin.overview.index', [
             'counters'       => $counters,
             'nodes'          => $nodes,
             'syncLastUpdate' => $syncLastUpdate,
+            'deletedNodesPresent'=> ($DBnodes->count() != count($pteroNodeIds))?true:false,
             'perPageLimit'   => ($counters['servers']->total != Server::query()->count())?true:false,
             'tickets'        => $tickets
         ]);

+ 38 - 0
app/Http/Controllers/Admin/ServerController.php

@@ -123,6 +123,44 @@ class ServerController extends Controller
         return redirect()->back()->with('success', __('Server has been updated!'));
     }
 
+    public function syncServers()
+    {
+        $pteroServers = Pterodactyl::getServers();
+        $CPServers = Server::get();
+
+        $CPIDArray = [];
+        $renameCount = 0;
+        foreach($CPServers as $CPServer)//go thru all CP servers and make array with IDs as keys. All values are false.
+        {
+            if($CPServer->pterodactyl_id) $CPIDArray[$CPServer->pterodactyl_id] = false;
+        }
+
+        foreach($pteroServers as $server)//go thru all ptero servers, if server exists, change value to true in array.
+        {
+            if(isset($CPIDArray[$server['attributes']['id']])){
+                $CPIDArray[$server['attributes']['id']]=true;
+
+                if(isset($server['attributes']['name'])){//failsafe
+                    //Check if a server got renamed
+                    $savedServer = Server::query()->where('pterodactyl_id', $server['attributes']['id'])->first();
+                    if($savedServer->name != $server['attributes']['name']){
+                        $savedServer->name = $server['attributes']['name'];
+                        $savedServer->save();
+                        $renameCount++;
+                    }
+                }
+            }
+        }
+        $filteredArray = array_filter($CPIDArray, function($v, $k) { return $v == false; }, ARRAY_FILTER_USE_BOTH); //Array of servers, that dont exist on ptero (value == false)
+        $deleteCount = 0;
+        foreach($filteredArray as $key => $CPID)//delete servers that dont exist on ptero anymore
+        {
+            if(!Pterodactyl::getServerAttributes($key, true)) $deleteCount++;
+        }
+
+        return redirect()->back()->with('success', __('Servers synced successfully' . (($renameCount)?(',\n' . __('renamed') . ' ' . $renameCount . ' ' . __('servers')):'') . ((count($filteredArray))?(',\n' . __('deleted') . ' ' . $deleteCount . '/' . count($filteredArray) . ' ' . __('old servers')):''))) . '.';
+    }
+
     /**
      * @return JsonResponse|mixed
      * @throws Exception

+ 8 - 1
app/Http/Controllers/Api/UserController.php

@@ -88,7 +88,7 @@ class UserController extends Controller
             "email" => "sometimes|string|email",
             "credits" => "sometimes|numeric|min:0|max:1000000",
             "server_limit" => "sometimes|numeric|min:0|max:1000000",
-            "role" => ['sometimes', Rule::in(['admin', 'mod', 'client', 'member'])],
+            "role" => ['sometimes', Rule::in(['admin', 'moderator', 'client', 'member'])],
         ]);
 
         event(new UserUpdateCreditsEvent($user));
@@ -251,6 +251,13 @@ class UserController extends Controller
             'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
             'password' => ['required', 'string', 'min:8', 'max:191'],
         ]);
+        
+        // Prevent the creation of new users via API if this is enabled.
+        if (!config('SETTINGS::SYSTEM:CREATION_OF_NEW_USERS', 'true')) {
+            throw ValidationException::withMessages([
+                'error' => "The creation of new users has been blocked by the system administrator."
+            ]);
+        } 
 
         $user = User::create([
             'name' => $request->input('name'),

+ 5 - 1
app/Http/Controllers/ProfileController.php

@@ -131,7 +131,11 @@ class ProfileController extends Controller
             'name' => $request->input('name'),
             'email' => $request->input('email'),
         ]);
-        $user->sendEmailVerificationNotification();
+
+        if ($request->input('email') != Auth::user()->email) {
+            $user->reVerifyEmail();
+            $user->sendEmailVerificationNotification();
+        };
 
         return redirect()->route('profile.index')->with('success', __('Profile updated'));
     }

+ 6 - 0
app/Http/Controllers/ServerController.php

@@ -135,6 +135,12 @@ class ServerController extends Controller
         if (config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', 'false') === 'true' && !Auth::user()->hasVerifiedEmail()) {
             return redirect()->route('profile.index')->with('error', __("You are required to verify your email address before you can create a server."));
         }
+        
+        //Required Verification for creating an server
+
+        if (!config('SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS', 'true') && Auth::user()->role != "admin") {
+            return redirect()->route('servers.index')->with('error', __("The system administrator has blocked the creation of new servers."));
+        }
 
         //Required Verification for creating an server
         if (config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', 'false') === 'true' && !Auth::user()->discordUser) {

+ 7 - 0
app/Models/User.php

@@ -266,4 +266,11 @@ class User extends Authenticatable implements MustVerifyEmail
             'email_verified_at' => now(),
         ])->save();
     }
+    
+    public function reVerifyEmail()
+    {
+        $this->forceFill([
+            'email_verified_at' => null,
+        ])->save();
+    }
 }

+ 1 - 1
config/app.php

@@ -4,7 +4,7 @@ use App\Models\Settings;
 
 return [
 
-    'version' => '0.8.3',
+    'version' => '0.8.3.1',
 
     /*
     |--------------------------------------------------------------------------

+ 16 - 2
database/seeders/Seeds/SettingsSeeder.php

@@ -518,9 +518,23 @@ class SettingsSeeder extends Seeder
         Settings::firstOrCreate([
             'key'   => 'SETTINGS::SYSTEM:ENABLE_UPGRADE',
         ], [
-            'value' =>"",
-            'type'  => 'string',
+            'value' =>  "false",
+            'type'  => 'boolean',
             'description'  => 'Enables the updgrade/downgrade feature for servers'
         ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS',
+        ], [
+            'value' => "true",
+            'type'  => 'boolean',
+            'description'  => 'Enable/disable the creation of new servers'
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::SYSTEM:CREATION_OF_NEW_USERS',
+        ], [
+            'value' => "true",
+            'type'  => 'boolean',
+            'description'  => 'Enable/disable the creation of new users'
+        ]);
     }
 }

File diff suppressed because it is too large
+ 0 - 0
resources/css/adminlte.min.css


+ 13 - 3
resources/views/admin/overview/index.blade.php

@@ -111,6 +111,14 @@
                             </div>
                         </div>
                         <div class="card-body py-1">
+                            @if ($deletedNodesPresent)
+                                <div class="alert alert-danger m-2">
+                                    <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Warning!') }}</h5>
+                                    <p class="mb-2">
+                                        {{ __('Some nodes got deleted on pterodactyl only. Please click the sync button above.') }}
+                                    </p>
+                                </div>
+                            @endif
                             <table class="table">
                                 <thead>
                                 <tr>
@@ -207,11 +215,13 @@
                             @if ($perPageLimit)
                                 <div class="alert alert-danger m-2">
                                     <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Error!') }}</h5>
-                                    <p class="">
+                                    <p class="mb-2">
                                         {{ __('You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.') }}<br>
-                                        {{ __('You can do that in settings.') }}<br>
-                                        {{ __('Note') }}: {{ __('If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on ControlPanel.') }}
+                                        {{ __('You can do that in settings.') }}<br><br>
+                                        {{ __('Note') }}: {{ __('If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on ControlPanel. Try clicking the button below.') }}
                                     </p>
+                                    <a href="{{route('admin.servers.sync')}}" class="btn btn-primary btn-md"><i
+                                        class="fas fa-sync mr-2"></i>{{__('Sync servers')}}</a>
                                 </div>
                             @endif
                             <table class="table">

+ 2 - 0
resources/views/admin/payments/index.blade.php

@@ -44,6 +44,7 @@
                                 <th>{{ __('Tax Value') }}</th>
                                 <th>{{ __('Tax Percentage') }}</th>
                                 <th>{{ __('Total Price') }}</th>
+                                <th>{{ __('User') }}</th>
                                 <th>{{ __('Payment ID') }}</th>
                                 <th>{{ __('Payment Method') }}</th>
                                 <th>{{ __('Created at') }}</th>
@@ -81,6 +82,7 @@
                     {data: 'tax_value'},
                     {data: 'tax_percent'},
                     {data: 'total_price'},
+                    {data: 'user'},
                     {data: 'payment_id'},
                     {data: 'payment_method'},
                     {data: 'created_at'},

+ 7 - 1
resources/views/admin/servers/index.blade.php

@@ -25,7 +25,13 @@
 
             <div class="card">
                 <div class="card-header">
-                    <h5 class="card-title"><i class="fas fa-server mr-2"></i>{{__('Servers')}}</h5>
+                    <div class="d-flex justify-content-between">
+                        <div class="card-title ">
+                            <span><i class="fas fa-server mr-2"></i>{{__('Servers')}}</span>
+                        </div>
+                        <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 class="card-body table-responsive">
 

+ 2 - 2
resources/views/admin/settings/tabs/misc.blade.php

@@ -195,8 +195,8 @@
                 </div>
                 @if(config('SETTINGS::RECAPTCHA:ENABLED') == 'true')
                 <div class="form-group mb-3">
-                    <div class="custom-control p-0">
-                        <label>{{ __('Your Recaptcha') }}:</label>
+                    <div class="custom-control p-0" style="transform:scale(0.77); transform-origin:0 0;">
+                        <label style="font-size: 1.3rem;">{{ __('Your Recaptcha') }}:</label>
                         {!! htmlScriptTagJsApi() !!}
                         {!! htmlFormSnippet() !!}
                     </div>

+ 25 - 3
resources/views/admin/settings/tabs/system.blade.php

@@ -128,12 +128,21 @@
                         <label for="force-discord-verification">{{ __('Force Discord verification') }}
                         </label>
                     </div>
-                    <div class="custom-control mb-3 p-0">
+                    <div class="custom-control mb-1 p-0">
                         <input value="true" id="force-email-verification" name="force-email-verification"
                             {{ config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION') == 'true' ? 'checked' : '' }}
                             type="checkbox">
                         <label for="force-email-verification">{{ __('Force E-Mail verification') }} </label>
                     </div>
+                    <div class="custom-control mb-3 p-0">
+                        <input value="true" id="enable-disable-new-users" name="enable-disable-new-users"
+                            {{ config('SETTINGS::SYSTEM:CREATION_OF_NEW_USERS') == 'true' ? 'checked' : '' }}
+                            type="checkbox">
+                        <label for="enable-disable-new-users">{{ __('Creation of new users') }} </label>
+                        <i data-toggle="popover" data-trigger="hover" data-html="true" class="fas fa-info-circle"
+                            data-content="{{ __('If unchecked, it will disable the registration of new users in the system, and this will also apply to the API.') }}">
+                        </i>
+                    </div>
 
                     <div class="custom-control mb-3 p-0">
                         <label for="initial-credits">{{ __('Initial Credits') }}</label>
@@ -209,6 +218,21 @@
                         </div>
                     </div>
                 </div>
+                <div class="form-group">
+                    <div class="custom-control mb-1 p-0">
+                        <div class="col m-0 p-0 d-flex justify-content-between align-items-center">
+                            <div>
+                                <input value="true" id="enable-disable-servers" name="enable-disable-servers"
+                                    {{ config('SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS') == 'true' ? 'checked' : '' }}
+                                    type="checkbox">
+                                <label for="enable-disable-servers">{{ __('Creation of new servers') }} </label>
+                            </div>
+                            <i data-toggle="popover" data-trigger="hover" data-html="true"
+                                data-content="{{ __('If unchecked, it will disable the creation of new servers for regular users and system moderators, this has no effect for administrators.') }}"
+                                class="fas fa-info-circle"></i>
+                        </div>
+                    </div>
+                </div>
                 <div class="form-group">
                     <div class="custom-control mb-3 p-0">
                         <div class="col m-0 p-0 d-flex justify-content-between align-items-center">
@@ -222,8 +246,6 @@
                             class="form-control @error('allocation-limit') is-invalid @enderror" required>
                     </div>
                 </div>
-
-
             </div>
 
                 {{-- Design --}}

+ 1 - 1
resources/views/admin/users/show.blade.php

@@ -6,7 +6,7 @@
         <div class="container-fluid">
             <div class="row mb-2">
                 <div class="col-sm-6">
-                    <h1{{__('Users')}}</h1>
+                    <h1>{{__('Users')}}</h1>
                 </div>
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">

+ 104 - 93
resources/views/auth/register.blade.php

@@ -2,118 +2,128 @@
 
 @section('content')
     <body class="hold-transition dark-mode register-page">
-    <div class="register-box">
-        <div class="card card-outline card-primary">
-            <div class="card-header text-center">
-                <a href="{{route('welcome')}}" class="h1"><b class="mr-1">{{config('app.name', 'Laravel')}}</b></a>
-            </div>
-            <div class="card-body">
-                <p class="login-box-msg">{{__('Register a new membership')}}</p>
+            <div class="register-box">
+                <div class="card card-outline card-primary">
+                    <div class="card-header text-center">
+                        <a href="{{route('welcome')}}" class="h1"><b class="mr-1">{{config('app.name', 'Laravel')}}</b></a>
+                    </div>
+                    <div class="card-body">
+                        @if(!config('SETTINGS::SYSTEM:CREATION_OF_NEW_USERS'))
+                        <div class="alert alert-warning p-2 m-2">
+                            <h5><i class="icon fas fa-exclamation-circle"></i> {{ __('Warning!') }}</h5>
+                            {{ __('The system administrator has blocked the registration of new users') }}
+                        </div>
+                        <div class="text-center">
+                            <a class="btn btn-primary" href="{{ route('login') }}">{{__('Back')}}</a>
+                        </div>
+                        @else
+                        <p class="login-box-msg">{{__('Register a new membership')}}</p>
 
-                <form method="POST" action="{{ route('register') }}">
+                        <form method="POST" action="{{ route('register') }}">
 
-                    @error('ip')
-                    <span class="text-danger" role="alert">
-                                <small><strong>{{ $message }}</strong></small>
-                            </span>
-                    @enderror
+                            @error('ip')
+                            <span class="text-danger" role="alert">
+                                        <small><strong>{{ $message }}</strong></small>
+                                    </span>
+                            @enderror
 
-                    @error('registered')
-                    <span class="text-danger" role="alert">
-                                <small><strong>{{ $message }}</strong></small>
-                            </span>
-                    @enderror
-                    @if( $errors->has('ptero_registration_error') )
-                        @foreach( $errors->get('ptero_registration_error') as $err )
+                            @error('registered')
                             <span class="text-danger" role="alert">
-                                 <small><strong>{{ $err }}</strong></small>
-                           </span>
-                        @endforeach
-                    @endif
+                                        <small><strong>{{ $message }}</strong></small>
+                                    </span>
+                            @enderror
+                            @if( $errors->has('ptero_registration_error') )
+                                @foreach( $errors->get('ptero_registration_error') as $err )
+                                    <span class="text-danger" role="alert">
+                                        <small><strong>{{ $err }}</strong></small>
+                                </span>
+                                @endforeach
+                            @endif
 
-                    @csrf
-                    <div class="form-group">
-                        <div class="input-group">
-                            <input type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}"
-                                   placeholder="{{__('Username')}}" required autocomplete="name" autofocus>
-                            <div class="input-group-append">
-                                <div class="input-group-text">
-                                    <span class="fas fa-user"></span>
+                            @csrf
+                            <div class="form-group">
+                                <div class="input-group">
+                                    <input type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}"
+                                        placeholder="{{__('Username')}}" required autocomplete="name" autofocus>
+                                    <div class="input-group-append">
+                                        <div class="input-group-text">
+                                            <span class="fas fa-user"></span>
+                                        </div>
+                                    </div>
                                 </div>
+                                @error('name')
+                                <span class="text-danger" role="alert">
+                                        <small><strong>{{ $message }}</strong></small>
+                                    </span>
+                                @enderror
                             </div>
-                        </div>
-                        @error('name')
-                        <span class="text-danger" role="alert">
-                                <small><strong>{{ $message }}</strong></small>
-                            </span>
-                        @enderror
-                    </div>
 
 
-                    <div class="form-group">
-                        <div class="input-group mb-3">
-                            <input type="email" name="email" class="form-control  @error('email') is-invalid @enderror" placeholder="{{__('Email')}}"
-                                   value="{{ old('email') }}" required autocomplete="email">
-                            <div class="input-group-append">
-                                <div class="input-group-text">
-                                    <span class="fas fa-envelope"></span>
+                            <div class="form-group">
+                                <div class="input-group mb-3">
+                                    <input type="email" name="email" class="form-control  @error('email') is-invalid @enderror" placeholder="{{__('Email')}}"
+                                        value="{{ old('email') }}" required autocomplete="email">
+                                    <div class="input-group-append">
+                                        <div class="input-group-text">
+                                            <span class="fas fa-envelope"></span>
+                                        </div>
+                                    </div>
                                 </div>
+                                @error('email')
+                                <span class="text-danger" role="alert">
+                                        <small><strong>{{ $message }}</strong></small>
+                                    </span>
+                                @enderror
                             </div>
-                        </div>
-                        @error('email')
-                        <span class="text-danger" role="alert">
-                                <small><strong>{{ $message }}</strong></small>
-                            </span>
-                        @enderror
-                    </div>
 
-                    <div class="form-group">
-                        <div class="input-group mb-3">
-                            <input type="password" class="form-control @error('password') is-invalid @enderror" placeholder="{{__('Password')}}" name="password" required autocomplete="new-password">
-                            <div class="input-group-append">
-                                <div class="input-group-text">
-                                    <span class="fas fa-lock"></span>
+                            <div class="form-group">
+                                <div class="input-group mb-3">
+                                    <input type="password" class="form-control @error('password') is-invalid @enderror" placeholder="{{__('Password')}}" name="password" required autocomplete="new-password">
+                                    <div class="input-group-append">
+                                        <div class="input-group-text">
+                                            <span class="fas fa-lock"></span>
+                                        </div>
+                                    </div>
                                 </div>
+                                @error('password')
+                                <span class="text-danger" role="alert">
+                                        <small><strong>{{ $message }}</strong></small>
+                                    </span>
+                                @enderror
                             </div>
-                        </div>
-                        @error('password')
-                        <span class="text-danger" role="alert">
-                                <small><strong>{{ $message }}</strong></small>
-                            </span>
-                        @enderror
-                    </div>
 
-                    <div class="input-group mb-3">
-                        <input type="password" class="form-control" name="password_confirmation" placeholder="{{__('Retype password')}}" required autocomplete="new-password">
-                        <div class="input-group-append">
-                            <div class="input-group-text">
-                                <span class="fas fa-lock"></span>
+                            <div class="input-group mb-3">
+                                <input type="password" class="form-control" name="password_confirmation" placeholder="{{__('Retype password')}}" required autocomplete="new-password">
+                                <div class="input-group-append">
+                                    <div class="input-group-text">
+                                        <span class="fas fa-lock"></span>
+                                    </div>
+                                </div>
                             </div>
-                        </div>
-                    </div>
-                    @if(config('SETTINGS::REFERRAL::ENABLED') == "true")
-                        <div class="input-group mb-3">
-                            <input type="text" value="{{ \Request::get('ref') }}" class="form-control" name="referral_code" placeholder="{{__('Referral code')}} ({{__("optional")}})">
-                            <div class="input-group-append">
-                                <div class="input-group-text">
-                                    <span class="fas fa-user-check"></span>
+                            @if(config('SETTINGS::REFERRAL::ENABLED') == "true")
+                                <div class="input-group mb-3">
+                                    <input type="text" value="{{ \Request::get('ref') }}" class="form-control" name="referral_code" placeholder="{{__('Referral code')}} ({{__("optional")}})">
+                                    <div class="input-group-append">
+                                        <div class="input-group-text">
+                                            <span class="fas fa-user-check"></span>
+                                        </div>
+                                    </div>
                                 </div>
+                            @endif
+                            @if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true')
+                            <div class="input-group mb-3">
+                                {!! htmlFormSnippet() !!}
+                                @error('g-recaptcha-response')
+                                <span class="text-danger" role="alert">
+                                        <small><strong>{{ $message }}</strong></small>
+                                    </span>
+                                @enderror
                             </div>
-                        </div>
-                    @endif
-                    @if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true')
-                    <div class="input-group mb-3">
-                        {!! htmlFormSnippet() !!}
-                        @error('g-recaptcha-response')
-                        <span class="text-danger" role="alert">
-                                <small><strong>{{ $message }}</strong></small>
-                            </span>
-                        @enderror
-                    </div>
-                    @endif
+                            @endif
+
+                            <div class="row">
+                                <div class="col-8">
 
-                    <div class="row">
-                        <div class="col-8">
 {{--                            <div class="icheck-primary">--}}
 {{--                                <input type="checkbox" id="agreeTerms" name="terms" value="agree">--}}
 {{--                                <label for="agreeTerms">--}}
@@ -147,4 +157,5 @@
     </div>
     <!-- /.register-box -->
     </body>
+    @endif
 @endsection

+ 6 - 1
resources/views/servers/create.blade.php

@@ -34,7 +34,12 @@
                             <div class="card-title"><i class="fas fa-cogs mr-2"></i>{{ __('Server configuration') }}
                             </div>
                         </div>
-
+                        @if (!config("SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS"))
+                            <div class="alert alert-warning p-2 m-2">
+                                The creation of new servers has been disabled for regular users, enable it again
+                                <a href="{{route('admin.settings.system')}}">{{ __('here') }}</a>.
+                            </div>
+                        @endif
                         @if ($productCount === 0 || $nodeCount === 0 || count($nests) === 0 || count($eggs) === 0)
                             <div class="alert alert-danger p-2 m-2">
                                 <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Error!') }}</h5>

+ 3 - 0
routes/web.php

@@ -128,6 +128,7 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
         #servers
         Route::get('servers/datatable', [AdminServerController::class, 'datatable'])->name('servers.datatable');
         Route::post('servers/togglesuspend/{server}', [AdminServerController::class, 'toggleSuspended'])->name('servers.togglesuspend');
+        Route::get('servers/sync', [AdminServerController::class, 'syncServers'])->name('servers.sync');
         Route::resource('servers', AdminServerController::class);
 
         #products
@@ -151,6 +152,8 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
         Route::get('settings/datatable', [SettingsController::class, 'datatable'])->name('settings.datatable');
         Route::patch('settings/updatevalue', [SettingsController::class, 'updatevalue'])->name('settings.updatevalue');
         Route::get("settings/checkPteroClientkey", [System::class, 'checkPteroClientkey'])->name('settings.checkPteroClientkey');
+        Route::redirect("settings#system", "system")->name('settings.system');
+
         #settings
         Route::patch('settings/update/invoice-settings', [Invoices::class, 'updateSettings'])->name('settings.update.invoicesettings');
         Route::patch('settings/update/language', [Language::class, 'updateSettings'])->name('settings.update.languagesettings');

Some files were not shown because too many files changed in this diff