From 86c8ecdcdf1520729ab48e37e310faf38bef18d6 Mon Sep 17 00:00:00 2001 From: stanjg Date: Fri, 4 May 2018 15:02:51 +0200 Subject: [PATCH 01/66] Added the actual logic --- app/Http/Kernel.php | 2 ++ app/Http/Middleware/MaintenanceMiddleware.php | 27 ++++++++++++++++ app/Models/Node.php | 5 ++- app/Providers/RouteServiceProvider.php | 2 +- ..._05_04_123826_add_maintenance_to_nodes.php | 32 +++++++++++++++++++ resources/lang/en/base.php | 5 +++ .../pterodactyl/errors/maintenance.blade.php | 30 +++++++++++++++++ 7 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 app/Http/Middleware/MaintenanceMiddleware.php create mode 100644 database/migrations/2018_05_04_123826_add_maintenance_to_nodes.php create mode 100644 resources/themes/pterodactyl/errors/maintenance.blade.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index b6d44530e..db01e70c3 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Http; +use Pterodactyl\Http\Middleware\MaintenanceMiddleware; use Pterodactyl\Models\ApiKey; use Illuminate\Auth\Middleware\Authorize; use Illuminate\Auth\Middleware\Authenticate; @@ -108,6 +109,7 @@ class Kernel extends HttpKernel 'can' => Authorize::class, 'bindings' => SubstituteBindings::class, 'recaptcha' => VerifyReCaptcha::class, + 'maintenance' => MaintenanceMiddleware::class, // Server specific middleware (used for authenticating access to resources) // diff --git a/app/Http/Middleware/MaintenanceMiddleware.php b/app/Http/Middleware/MaintenanceMiddleware.php new file mode 100644 index 000000000..493582809 --- /dev/null +++ b/app/Http/Middleware/MaintenanceMiddleware.php @@ -0,0 +1,27 @@ +attributes->get('server'); + $node = $server->node; + + if ($node->maintenance) { + return response(view('errors.maintenance')); + } + + return $next($request); + } +} diff --git a/app/Models/Node.php b/app/Models/Node.php index 26d9eb443..ea0258e8f 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -48,6 +48,7 @@ class Node extends Model implements CleansAttributes, ValidableContract 'daemonSFTP' => 'integer', 'behind_proxy' => 'boolean', 'public' => 'boolean', + 'maintenance' => 'boolean', ]; /** @@ -62,7 +63,7 @@ class Node extends Model implements CleansAttributes, ValidableContract 'disk_overallocate', 'upload_size', 'daemonSecret', 'daemonBase', 'daemonSFTP', 'daemonListen', - 'description', + 'description', 'maintenance', ]; /** @@ -111,6 +112,7 @@ class Node extends Model implements CleansAttributes, ValidableContract 'daemonBase' => 'regex:/^([\/][\d\w.\-\/]+)$/', 'daemonSFTP' => 'numeric|between:1024,65535', 'daemonListen' => 'numeric|between:1024,65535', + 'maintenance' => 'boolean', ]; /** @@ -126,6 +128,7 @@ class Node extends Model implements CleansAttributes, ValidableContract 'daemonBase' => '/srv/daemon-data', 'daemonSFTP' => 2022, 'daemonListen' => 8080, + 'maintenance' => false, ]; /** diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 3de307d9a..3604b3d79 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -33,7 +33,7 @@ class RouteServiceProvider extends ServiceProvider ->namespace($this->namespace . '\Auth') ->group(base_path('routes/auth.php')); - Route::middleware(['web', 'csrf', 'auth', 'server', 'subuser.auth'])->prefix('/server/{server}') + Route::middleware(['web', 'csrf', 'auth', 'server', 'subuser.auth', 'maintenance'])->prefix('/server/{server}') ->namespace($this->namespace . '\Server') ->group(base_path('routes/server.php')); diff --git a/database/migrations/2018_05_04_123826_add_maintenance_to_nodes.php b/database/migrations/2018_05_04_123826_add_maintenance_to_nodes.php new file mode 100644 index 000000000..6c55912aa --- /dev/null +++ b/database/migrations/2018_05_04_123826_add_maintenance_to_nodes.php @@ -0,0 +1,32 @@ +boolean('maintenance')->after('behind_proxy')->default(false); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('nodes', function (Blueprint $table) { + $table->dropColumn('maintenance'); + }); + } +} diff --git a/resources/lang/en/base.php b/resources/lang/en/base.php index ee3fb1f37..1603f4a17 100644 --- a/resources/lang/en/base.php +++ b/resources/lang/en/base.php @@ -21,6 +21,11 @@ return [ 'header' => 'Server Suspended', 'desc' => 'This server has been suspended and cannot be accessed.', ], + 'maintenance' => [ + 'header' => 'Node Under Maintenance', + 'title' => 'Maintenance', + 'desc' => 'This node is under maintenance, therefore your server can temporarily not be accessed.' + ], ], 'index' => [ 'header' => 'Your Servers', diff --git a/resources/themes/pterodactyl/errors/maintenance.blade.php b/resources/themes/pterodactyl/errors/maintenance.blade.php new file mode 100644 index 000000000..97bb810e5 --- /dev/null +++ b/resources/themes/pterodactyl/errors/maintenance.blade.php @@ -0,0 +1,30 @@ +{{-- Pterodactyl - Panel --}} +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- This software is licensed under the terms of the MIT license. --}} +{{-- https://opensource.org/licenses/MIT --}} +@extends('layouts.error') + +@section('title') + @lang('base.errors.maintenance.header') +@endsection + +@section('content-header') +@endsection + +@section('content') +
+
+
+
+

@lang('base.errors.maintenance.title')

+

@lang('base.errors.maintenance.desc')

+
+ +
+
+
+@endsection From baea1d61912d16ae76bc0841142d820cb706e6a9 Mon Sep 17 00:00:00 2001 From: stanjg Date: Fri, 4 May 2018 15:13:34 +0200 Subject: [PATCH 02/66] Added the option to toggle, and made it display on the details page --- .../pterodactyl/admin/nodes/view/index.blade.php | 11 +++++++++++ .../admin/nodes/view/settings.blade.php | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/resources/themes/pterodactyl/admin/nodes/view/index.blade.php b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php index 76a2ca627..2880fba51 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/index.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php @@ -96,6 +96,17 @@
+ @if($node->maintenance) +
+
+ +
+ This node is under + Maintenance +
+
+
+ @endif
diff --git a/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php b/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php index 919ad958b..ba9a952b7 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php @@ -108,6 +108,20 @@

If you are running the daemon behind a proxy such as Cloudflare, select this to have the daemon skip looking for certificates on boot.

+
+ +
+
+ maintenance) == false) ? 'checked' : '' }}> + +
+
+ maintenance) == true) ? 'checked' : '' }}> + +
+
+

If the node is marked as 'Under Maintenance' users won't be able to access servers that are on this node.

+
From f39720f15db760e05a49c691d8b545d196e6592b Mon Sep 17 00:00:00 2001 From: stanjg Date: Fri, 4 May 2018 15:16:14 +0200 Subject: [PATCH 03/66] Made it display 'maintenance' on the index page --- resources/themes/pterodactyl/base/index.blade.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/resources/themes/pterodactyl/base/index.blade.php b/resources/themes/pterodactyl/base/index.blade.php index 95cce6128..09596298c 100644 --- a/resources/themes/pterodactyl/base/index.blade.php +++ b/resources/themes/pterodactyl/base/index.blade.php @@ -64,9 +64,15 @@ @lang('strings.subuser') @endif - - - + @if($server->node->maintenance) + + Maintenance + + @else + + + + @endif @if (! empty($server->description)) From 93a7d11c28d8423741b6d01d57e6dfaf5de97e0e Mon Sep 17 00:00:00 2001 From: stanjg Date: Fri, 4 May 2018 18:45:37 +0200 Subject: [PATCH 04/66] Made a base --- .../Admin/StatisticsController.php | 59 ++++++++++ public/themes/pterodactyl/css/pterodactyl.css | 4 + .../themes/pterodactyl/js/admin/statistics.js | 101 +++++++++++++++++ .../pterodactyl/admin/statistics.blade.php | 103 ++++++++++++++++++ .../pterodactyl/layouts/admin.blade.php | 5 + routes/admin.php | 1 + 6 files changed, 273 insertions(+) create mode 100644 app/Http/Controllers/Admin/StatisticsController.php create mode 100644 public/themes/pterodactyl/js/admin/statistics.js create mode 100644 resources/themes/pterodactyl/admin/statistics.blade.php diff --git a/app/Http/Controllers/Admin/StatisticsController.php b/app/Http/Controllers/Admin/StatisticsController.php new file mode 100644 index 000000000..499b52cd4 --- /dev/null +++ b/app/Http/Controllers/Admin/StatisticsController.php @@ -0,0 +1,59 @@ +sum('memory'); + $totalNodeRam = DB::table('nodes')->sum('memory'); + $totalServerDisk = DB::table('servers')->sum('disk'); + $totalNodeDisk = DB::table('nodes')->sum('disk'); + $totalAllocations = Allocation::count(); + + $suspendedServersCount = Server::where('suspended', true)->count(); + + Javascript::put([ + 'servers' => Server::all(), + 'serverCount' => $serversCount, + 'suspendedServers' => $suspendedServersCount, + 'totalServerRam' => $totalServerRam, + 'totalNodeRam' => $totalNodeRam, + 'totalServerDisk' => $totalServerDisk, + 'totalNodeDisk' => $totalNodeDisk, + ]); + + return view('admin.statistics', [ + 'serversCount' => $serversCount, + 'nodesCount' => $nodesCount, + 'usersCount' => $usersCount, + 'eggsCount' => $eggsCount, + 'totalServerRam' => $totalServerRam, + 'databasesCount' => $databasesCount, + 'totalNodeRam' => $totalNodeRam, + 'totalNodeDisk' => $totalNodeDisk, + 'totalServerDisk' => $totalServerDisk, + 'totalAllocations' => $totalAllocations, + ]); + } + +} diff --git a/public/themes/pterodactyl/css/pterodactyl.css b/public/themes/pterodactyl/css/pterodactyl.css index 9e7e6a822..41f163f3b 100644 --- a/public/themes/pterodactyl/css/pterodactyl.css +++ b/public/themes/pterodactyl/css/pterodactyl.css @@ -473,3 +473,7 @@ label.control-label > span.field-optional:before { height: 42px; width: auto; } + +.number-info-box-content { + padding: 15px 10px 0; +} diff --git a/public/themes/pterodactyl/js/admin/statistics.js b/public/themes/pterodactyl/js/admin/statistics.js new file mode 100644 index 000000000..b5bdbe4a1 --- /dev/null +++ b/public/themes/pterodactyl/js/admin/statistics.js @@ -0,0 +1,101 @@ +var freeDisk = Pterodactyl.totalNodeDisk - Pterodactyl.totalServerDisk; +let diskChart = new Chart($('#disk_chart'), { + type: 'pie', + data: { + labels: ['Free Disk', 'Used Disk'], + datasets: [ + { + label: 'Disk in MBs', + backgroundColor: ['#51B060', '#ff0000'], + data: [freeDisk, Pterodactyl.totalServerDisk] + } + ] + } +}); + +var freeRam = Pterodactyl.totalNodeRam - Pterodactyl.totalServerRam; +let ramChart = new Chart($('#ram_chart'), { + type: 'pie', + data: { + labels: ['Free RAM', 'Used RAM'], + datasets: [ + { + label: 'RAM in MBs', + backgroundColor: ['#51B060', '#ff0000'], + data: [freeRam, Pterodactyl.totalServerRam] + } + ] + } +}); + +var activeServers = Pterodactyl.serverCount - Pterodactyl.suspendedServers; +let serversChart = new Chart($('#servers_chart'), { + type: 'pie', + data: { + labels: ['Active', 'Suspended'], + datasets: [ + { + label: 'Servers', + backgroundColor: ['#51B060', '#E08E0B'], + data: [activeServers, Pterodactyl.suspendedServers] + } + ] + } +}); + +let statusChart = new Chart($('#status_chart'), { + type: 'pie', + data: { + labels: ['Online', 'Offline', 'Installing', 'Error'], + datasets: [ + { + label: '', + backgroundColor: ['#51B060', '#b7b7b7', '#E08E0B', '#ff0000'], + data: [0,0,0,0] + } + ] + } +}); + +var servers = Pterodactyl.servers; +servers.forEach(function (server) { + $.ajax({ + type: 'GET', + url: Router.route('index.status', { server: server.uuidShort}), + timeout: 5000, + headers: { + 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'), + } + }).done(function (data) { + + if (typeof data.status === 'undefined') { + // Error + statusChart.data.datasets[0].data[3]++; + return; + } + + switch (data.status) { + case 0: + case 3: + case 30: + // Offline + statusChart.data.datasets[0].data[1]++; + break; + case 1: + case 2: + // Online + console.log('online'); + statusChart.data.datasets[0].data[0]++; + break; + case 20: + // Installing + statusChart.data.datasets[0].data[2]++; + break; + } + statusChart.update(); + }).fail(function (jqXHR) { + // Error + statusChart.data.datasets[0].data[3]++; + statusChart.update(); + }); +}); \ No newline at end of file diff --git a/resources/themes/pterodactyl/admin/statistics.blade.php b/resources/themes/pterodactyl/admin/statistics.blade.php new file mode 100644 index 000000000..0579093af --- /dev/null +++ b/resources/themes/pterodactyl/admin/statistics.blade.php @@ -0,0 +1,103 @@ +@extends('layouts.admin') +@include('partials/admin.settings.nav', ['activeTab' => 'basic']) + +@section('title') + Statistics Overview +@endsection + +@section('content-header') +

Statistics OverviewMonitor your panel usage.

+ +@endsection + +@section('content') +
+
+
+
+ Servers +
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+ Servers + {{ $serversCount }} +
+
+
+ +
+ Total used RAM + {{ $totalServerRam }}MB +
+
+
+ +
+ Total used disk space + {{ $totalServerDisk }}MB +
+
+
+
+
+
+
+
+ Nodes +
+ +
+ +
+
+ +
+
+
+
+
+
+ +
+ Total RAM + {{ $totalNodeRam }}MB +
+
+
+ +
+ Total Disk Space + {{ $totalNodeDisk }}MB +
+
+
+ +
+ Total Allocations + {{ $totalAllocations }} +
+
+
+
+@endsection + +@section('footer-scripts') + @parent + {!! Theme::js('vendor/chartjs/chart.min.js') !!} + {!! Theme::js('js/admin/statistics.js') !!} +@endsection \ No newline at end of file diff --git a/resources/themes/pterodactyl/layouts/admin.blade.php b/resources/themes/pterodactyl/layouts/admin.blade.php index d67eb6b41..aaf8f4cac 100644 --- a/resources/themes/pterodactyl/layouts/admin.blade.php +++ b/resources/themes/pterodactyl/layouts/admin.blade.php @@ -80,6 +80,11 @@ Overview +
  • + + Statistics + +
  • Settings diff --git a/routes/admin.php b/routes/admin.php index 7dfa94f09..70ba7e3d1 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -1,6 +1,7 @@ name('admin.index'); +Route::get('/statistics', 'StatisticsController@index')->name('admin.statistics'); /* |-------------------------------------------------------------------------- From 28a97fea54351d8d00f64220483688202b9efd07 Mon Sep 17 00:00:00 2001 From: stanjg Date: Fri, 4 May 2018 22:48:43 +0200 Subject: [PATCH 05/66] Polished it up --- .../Admin/StatisticsController.php | 22 ++++++++++- .../themes/pterodactyl/js/admin/statistics.js | 30 ++++++++++++--- .../pterodactyl/admin/statistics.blade.php | 38 +++++++++++++++++++ 3 files changed, 84 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Admin/StatisticsController.php b/app/Http/Controllers/Admin/StatisticsController.php index 499b52cd4..119adb086 100644 --- a/app/Http/Controllers/Admin/StatisticsController.php +++ b/app/Http/Controllers/Admin/StatisticsController.php @@ -12,13 +12,22 @@ use Pterodactyl\Models\Server; use Pterodactyl\Models\User; use JavaScript; use Illuminate\Support\Facades\DB; +use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; class StatisticsController extends Controller { + private $keyProviderService; + + function __construct(DaemonKeyProviderService $keyProviderService) + { + $this->keyProviderService = $keyProviderService; + } + public function index(Request $request) { $servers = Server::all(); + $nodes = Node::all(); $serversCount = count($servers); $nodesCount = Node::count(); $usersCount = User::count(); @@ -29,17 +38,26 @@ class StatisticsController extends Controller $totalServerDisk = DB::table('servers')->sum('disk'); $totalNodeDisk = DB::table('nodes')->sum('disk'); $totalAllocations = Allocation::count(); + $totalUsersCount = User::count(); + $totalDBCount = Database::count(); $suspendedServersCount = Server::where('suspended', true)->count(); + $tokens = []; + foreach ($nodes as $node) { + $tokens[$node->id] = $this->keyProviderService->handle($node->servers->get(0), $request->user()); + } + Javascript::put([ - 'servers' => Server::all(), + 'servers' => $servers, 'serverCount' => $serversCount, 'suspendedServers' => $suspendedServersCount, 'totalServerRam' => $totalServerRam, 'totalNodeRam' => $totalNodeRam, 'totalServerDisk' => $totalServerDisk, 'totalNodeDisk' => $totalNodeDisk, + 'nodes' => $nodes, + 'tokens' => $tokens, ]); return view('admin.statistics', [ @@ -53,6 +71,8 @@ class StatisticsController extends Controller 'totalNodeDisk' => $totalNodeDisk, 'totalServerDisk' => $totalServerDisk, 'totalAllocations' => $totalAllocations, + 'totalUsersCount' => $totalUsersCount, + 'totalDBCount' => $totalDBCount, ]); } diff --git a/public/themes/pterodactyl/js/admin/statistics.js b/public/themes/pterodactyl/js/admin/statistics.js index b5bdbe4a1..f2c1c13dd 100644 --- a/public/themes/pterodactyl/js/admin/statistics.js +++ b/public/themes/pterodactyl/js/admin/statistics.js @@ -58,13 +58,25 @@ let statusChart = new Chart($('#status_chart'), { }); var servers = Pterodactyl.servers; -servers.forEach(function (server) { +var nodes = Pterodactyl.nodes; + +for (let i = 0; i < servers.length; i++) { + setTimeout(getStatus, 200 * i); +} + +var index = 0; +function getStatus() { + var server = servers[index]; + var uuid = server.uuid; + var node = getNodeByID(server.node_id); + $.ajax({ type: 'GET', - url: Router.route('index.status', { server: server.uuidShort}), + url: node.scheme + '://' + node.fqdn + ':'+node.daemonListen+'/v1/server', timeout: 5000, headers: { - 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'), + 'X-Access-Server': uuid, + 'X-Access-Token': Pterodactyl.tokens[node.id], } }).done(function (data) { @@ -84,7 +96,6 @@ servers.forEach(function (server) { case 1: case 2: // Online - console.log('online'); statusChart.data.datasets[0].data[0]++; break; case 20: @@ -98,4 +109,13 @@ servers.forEach(function (server) { statusChart.data.datasets[0].data[3]++; statusChart.update(); }); -}); \ No newline at end of file + + index++; +} + +function getNodeByID(id) { + for (var i = 0; i < nodes.length; i++) { + if (nodes[i].id === id) + return nodes[i]; + } +} \ No newline at end of file diff --git a/resources/themes/pterodactyl/admin/statistics.blade.php b/resources/themes/pterodactyl/admin/statistics.blade.php index 0579093af..e8e7cc255 100644 --- a/resources/themes/pterodactyl/admin/statistics.blade.php +++ b/resources/themes/pterodactyl/admin/statistics.blade.php @@ -94,6 +94,44 @@ +
    +
    +
    + +
    + Total Eggs + {{ $eggsCount }} +
    +
    +
    +
    +
    + +
    + Total Users + {{ $totalUsersCount }} +
    +
    +
    +
    +
    + +
    + Total Nodes + {{ $nodesCount }} +
    +
    +
    +
    +
    + +
    + Total Databases + {{ $totalDBCount }} +
    +
    +
    +
    @endsection @section('footer-scripts') From ee50da0a7c2538fa7ed337424833b431d54280b3 Mon Sep 17 00:00:00 2001 From: stanjg Date: Fri, 4 May 2018 23:35:45 +0200 Subject: [PATCH 06/66] Fixed a typo --- resources/themes/pterodactyl/admin/statistics.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/themes/pterodactyl/admin/statistics.blade.php b/resources/themes/pterodactyl/admin/statistics.blade.php index e8e7cc255..dff5019e4 100644 --- a/resources/themes/pterodactyl/admin/statistics.blade.php +++ b/resources/themes/pterodactyl/admin/statistics.blade.php @@ -60,14 +60,14 @@
    Nodes
    - +
    - +
    From 06a67bb4bb2a786132f4731a14168446eb403356 Mon Sep 17 00:00:00 2001 From: stanjg Date: Sat, 5 May 2018 10:39:20 +0200 Subject: [PATCH 07/66] Cleaned up some duplicate code --- app/Http/Controllers/Admin/StatisticsController.php | 4 ---- resources/themes/pterodactyl/admin/statistics.blade.php | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Admin/StatisticsController.php b/app/Http/Controllers/Admin/StatisticsController.php index 119adb086..a3777e4e7 100644 --- a/app/Http/Controllers/Admin/StatisticsController.php +++ b/app/Http/Controllers/Admin/StatisticsController.php @@ -38,8 +38,6 @@ class StatisticsController extends Controller $totalServerDisk = DB::table('servers')->sum('disk'); $totalNodeDisk = DB::table('nodes')->sum('disk'); $totalAllocations = Allocation::count(); - $totalUsersCount = User::count(); - $totalDBCount = Database::count(); $suspendedServersCount = Server::where('suspended', true)->count(); @@ -71,8 +69,6 @@ class StatisticsController extends Controller 'totalNodeDisk' => $totalNodeDisk, 'totalServerDisk' => $totalServerDisk, 'totalAllocations' => $totalAllocations, - 'totalUsersCount' => $totalUsersCount, - 'totalDBCount' => $totalDBCount, ]); } diff --git a/resources/themes/pterodactyl/admin/statistics.blade.php b/resources/themes/pterodactyl/admin/statistics.blade.php index dff5019e4..46e112336 100644 --- a/resources/themes/pterodactyl/admin/statistics.blade.php +++ b/resources/themes/pterodactyl/admin/statistics.blade.php @@ -109,7 +109,7 @@
    Total Users - {{ $totalUsersCount }} + {{ $usersCount }}
    @@ -127,7 +127,7 @@
    Total Databases - {{ $totalDBCount }} + {{ $databasesCount }}
    From 095d85bb60cb283596ff7879bcc567924157da53 Mon Sep 17 00:00:00 2001 From: stanjg Date: Sun, 6 May 2018 17:59:11 +0200 Subject: [PATCH 08/66] Added the server as argument, and improved the bug fix --- app/Http/Controllers/Admin/StatisticsController.php | 12 ++++++++---- public/themes/pterodactyl/js/admin/statistics.js | 11 ++++------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/Http/Controllers/Admin/StatisticsController.php b/app/Http/Controllers/Admin/StatisticsController.php index a3777e4e7..aedca3d6b 100644 --- a/app/Http/Controllers/Admin/StatisticsController.php +++ b/app/Http/Controllers/Admin/StatisticsController.php @@ -3,6 +3,8 @@ namespace Pterodactyl\Http\Controllers\Admin; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; +use JavaScript; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Models\Allocation; use Pterodactyl\Models\Database; @@ -10,8 +12,6 @@ use Pterodactyl\Models\Egg; use Pterodactyl\Models\Node; use Pterodactyl\Models\Server; use Pterodactyl\Models\User; -use JavaScript; -use Illuminate\Support\Facades\DB; use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; class StatisticsController extends Controller @@ -29,7 +29,7 @@ class StatisticsController extends Controller $servers = Server::all(); $nodes = Node::all(); $serversCount = count($servers); - $nodesCount = Node::count(); + $nodesCount = count($nodes); $usersCount = User::count(); $eggsCount = Egg::count(); $databasesCount = Database::count(); @@ -43,7 +43,11 @@ class StatisticsController extends Controller $tokens = []; foreach ($nodes as $node) { - $tokens[$node->id] = $this->keyProviderService->handle($node->servers->get(0), $request->user()); + $server = Server::where('node_id', $node->id)->first(); + if ($server == null) + continue; + + $tokens[$node->id] = $this->keyProviderService->handle($server, $request->user()); } Javascript::put([ diff --git a/public/themes/pterodactyl/js/admin/statistics.js b/public/themes/pterodactyl/js/admin/statistics.js index f2c1c13dd..12f4277bd 100644 --- a/public/themes/pterodactyl/js/admin/statistics.js +++ b/public/themes/pterodactyl/js/admin/statistics.js @@ -61,12 +61,10 @@ var servers = Pterodactyl.servers; var nodes = Pterodactyl.nodes; for (let i = 0; i < servers.length; i++) { - setTimeout(getStatus, 200 * i); + setTimeout(getStatus, 200 * i, servers[i]); } -var index = 0; -function getStatus() { - var server = servers[index]; +function getStatus(server) { var uuid = server.uuid; var node = getNodeByID(server.node_id); @@ -109,13 +107,12 @@ function getStatus() { statusChart.data.datasets[0].data[3]++; statusChart.update(); }); - - index++; } function getNodeByID(id) { for (var i = 0; i < nodes.length; i++) { - if (nodes[i].id === id) + if (nodes[i].id === id) { return nodes[i]; + } } } \ No newline at end of file From 5f6ee45f445aaf784d50e7996e2da9c6cedafcf1 Mon Sep 17 00:00:00 2001 From: Xander Smeets Date: Sun, 6 May 2018 20:22:30 +0200 Subject: [PATCH 09/66] Fixed typo (#1134) --- app/Notifications/AccountCreated.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Notifications/AccountCreated.php b/app/Notifications/AccountCreated.php index 8312c3bd1..29b084d5e 100644 --- a/app/Notifications/AccountCreated.php +++ b/app/Notifications/AccountCreated.php @@ -60,7 +60,7 @@ class AccountCreated extends Notification implements ShouldQueue { $message = (new MailMessage) ->greeting('Hello ' . $this->user->name . '!') - ->line('You are recieving this email because an account has been created for you on ' . config('app.name') . '.') + ->line('You are receiving this email because an account has been created for you on ' . config('app.name') . '.') ->line('Username: ' . $this->user->username) ->line('Email: ' . $this->user->email); From ba96829d13fcd5818941dca63f97d2182c96afbe Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sun, 13 May 2018 00:41:56 -0400 Subject: [PATCH 10/66] Fix cron jobs by removing the extra unusable argument --- app/Services/Schedules/ProcessScheduleService.php | 2 +- app/Services/Schedules/ScheduleCreationService.php | 2 +- app/Services/Schedules/ScheduleUpdateService.php | 2 +- tests/Unit/Services/Schedules/ProcessScheduleServiceTest.php | 2 +- tests/Unit/Services/Schedules/ScheduleCreationServiceTest.php | 4 ++-- tests/Unit/Services/Schedules/ScheduleUpdateServiceTest.php | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/Services/Schedules/ProcessScheduleService.php b/app/Services/Schedules/ProcessScheduleService.php index ec6ea5f12..b134caa35 100644 --- a/app/Services/Schedules/ProcessScheduleService.php +++ b/app/Services/Schedules/ProcessScheduleService.php @@ -63,7 +63,7 @@ class ProcessScheduleService { $this->repository->loadTasks($schedule); - $formattedCron = sprintf('%s %s %s * %s *', + $formattedCron = sprintf('%s %s %s * %s', $schedule->cron_minute, $schedule->cron_hour, $schedule->cron_day_of_month, diff --git a/app/Services/Schedules/ScheduleCreationService.php b/app/Services/Schedules/ScheduleCreationService.php index 9f676e246..c8cbd7fb3 100644 --- a/app/Services/Schedules/ScheduleCreationService.php +++ b/app/Services/Schedules/ScheduleCreationService.php @@ -86,7 +86,7 @@ class ScheduleCreationService */ private function getCronTimestamp(array $data) { - $formattedCron = sprintf('%s %s %s * %s *', + $formattedCron = sprintf('%s %s %s * %s', array_get($data, 'cron_minute', '*'), array_get($data, 'cron_hour', '*'), array_get($data, 'cron_day_of_month', '*'), diff --git a/app/Services/Schedules/ScheduleUpdateService.php b/app/Services/Schedules/ScheduleUpdateService.php index 96da1b106..1ddbbd242 100644 --- a/app/Services/Schedules/ScheduleUpdateService.php +++ b/app/Services/Schedules/ScheduleUpdateService.php @@ -98,7 +98,7 @@ class ScheduleUpdateService */ private function getCronTimestamp(array $data) { - $formattedCron = sprintf('%s %s %s * %s *', + $formattedCron = sprintf('%s %s %s * %s', array_get($data, 'cron_minute', '*'), array_get($data, 'cron_hour', '*'), array_get($data, 'cron_day_of_month', '*'), diff --git a/tests/Unit/Services/Schedules/ProcessScheduleServiceTest.php b/tests/Unit/Services/Schedules/ProcessScheduleServiceTest.php index 67db3b626..27e20082a 100644 --- a/tests/Unit/Services/Schedules/ProcessScheduleServiceTest.php +++ b/tests/Unit/Services/Schedules/ProcessScheduleServiceTest.php @@ -60,7 +60,7 @@ class ProcessScheduleServiceTest extends TestCase $this->repository->shouldReceive('loadTasks')->with($model)->once()->andReturn($model); - $formatted = sprintf('%s %s %s * %s *', $model->cron_minute, $model->cron_hour, $model->cron_day_of_month, $model->cron_day_of_week); + $formatted = sprintf('%s %s %s * %s', $model->cron_minute, $model->cron_hour, $model->cron_day_of_month, $model->cron_day_of_week); $this->repository->shouldReceive('update')->with($model->id, [ 'is_processing' => true, 'next_run_at' => CronExpression::factory($formatted)->getNextRunDate(), diff --git a/tests/Unit/Services/Schedules/ScheduleCreationServiceTest.php b/tests/Unit/Services/Schedules/ScheduleCreationServiceTest.php index 62d875fcd..117d4a86f 100644 --- a/tests/Unit/Services/Schedules/ScheduleCreationServiceTest.php +++ b/tests/Unit/Services/Schedules/ScheduleCreationServiceTest.php @@ -64,7 +64,7 @@ class ScheduleCreationServiceTest extends TestCase $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); $this->repository->shouldReceive('create')->with([ 'server_id' => $server->id, - 'next_run_at' => CronExpression::factory('* * * * * *')->getNextRunDate(), + 'next_run_at' => CronExpression::factory('* * * * *')->getNextRunDate(), 'test_key' => 'value', ])->once()->andReturn($schedule); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); @@ -85,7 +85,7 @@ class ScheduleCreationServiceTest extends TestCase $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); $this->repository->shouldReceive('create')->with([ 'server_id' => $server->id, - 'next_run_at' => CronExpression::factory('* * * * * *')->getNextRunDate(), + 'next_run_at' => CronExpression::factory('* * * * *')->getNextRunDate(), 'test_key' => 'value', ])->once()->andReturn($schedule); diff --git a/tests/Unit/Services/Schedules/ScheduleUpdateServiceTest.php b/tests/Unit/Services/Schedules/ScheduleUpdateServiceTest.php index 3f26f69b9..4a4dc20db 100644 --- a/tests/Unit/Services/Schedules/ScheduleUpdateServiceTest.php +++ b/tests/Unit/Services/Schedules/ScheduleUpdateServiceTest.php @@ -64,7 +64,7 @@ class ScheduleUpdateServiceTest extends TestCase $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs(); $this->repository->shouldReceive('update')->once()->with($schedule->id, array_merge($data, [ - 'next_run_at' => CronExpression::factory('1 2 3 * 4 *')->getNextRunDate(), + 'next_run_at' => CronExpression::factory('1 2 3 * 4')->getNextRunDate(), ]))->andReturn($schedule); $this->taskRepository->shouldReceive('deleteWhere')->once()->with([['schedule_id', '=', $schedule->id]]); From 351099ccf512f23e7936d4125d6a71051cf74ef3 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sun, 13 May 2018 10:13:51 -0400 Subject: [PATCH 11/66] Rename identitity to identity --- resources/lang/de/base.php | 2 +- resources/lang/en/base.php | 2 +- resources/lang/es/base.php | 2 +- resources/themes/pterodactyl/base/account.blade.php | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/lang/de/base.php b/resources/lang/de/base.php index b482e9af5..6d547def7 100644 --- a/resources/lang/de/base.php +++ b/resources/lang/de/base.php @@ -220,7 +220,7 @@ return [ 'new_email' => 'Neue Email Adresse', 'first_name' => 'Vornahme', 'last_name' => 'Nachname', - 'update_identitity' => 'Account bearbeiten', + 'update_identity' => 'Account bearbeiten', 'username_help' => 'Dein Username darf nicht bereits vergeben sein oder folgende Zeichen enthakten: :requirements.', ], 'security' => [ diff --git a/resources/lang/en/base.php b/resources/lang/en/base.php index ee3fb1f37..51b18546d 100644 --- a/resources/lang/en/base.php +++ b/resources/lang/en/base.php @@ -62,7 +62,7 @@ return [ 'new_email' => 'New Email Address', 'first_name' => 'First Name', 'last_name' => 'Last Name', - 'update_identitity' => 'Update Identity', + 'update_identity' => 'Update Identity', 'username_help' => 'Your username must be unique to your account, and may only contain the following characters: :requirements.', ], 'security' => [ diff --git a/resources/lang/es/base.php b/resources/lang/es/base.php index 0593be075..93dca11bd 100644 --- a/resources/lang/es/base.php +++ b/resources/lang/es/base.php @@ -220,7 +220,7 @@ return [ 'new_email' => 'Nueva Dirección De Correo Electrónico', 'first_name' => 'Primer Nombre', 'last_name' => 'Apellido', - 'update_identitity' => 'Actualización De La Identidad', + 'update_identity' => 'Actualización De La Identidad', 'username_help' => 'Su nombre de usuario debe ser único a su cuenta, y sólo pueden contener los siguientes caracteres: :requirements.', ], 'security' => [ diff --git a/resources/themes/pterodactyl/base/account.blade.php b/resources/themes/pterodactyl/base/account.blade.php index 3c202f570..2fd8294e3 100644 --- a/resources/themes/pterodactyl/base/account.blade.php +++ b/resources/themes/pterodactyl/base/account.blade.php @@ -64,7 +64,7 @@
    -

    @lang('base.account.update_identitity')

    +

    @lang('base.account.update_identity')

    @@ -94,7 +94,7 @@
    From 84edec632329729020fbf5c234d0b8169a5a917b Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sun, 13 May 2018 10:18:30 -0400 Subject: [PATCH 12/66] Spelling fixes in the english translation --- resources/lang/en/admin/server.php | 2 +- resources/lang/en/base.php | 8 ++++---- resources/lang/en/command/messages.php | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/lang/en/admin/server.php b/resources/lang/en/admin/server.php index e0ccdba77..fa254c8d9 100644 --- a/resources/lang/en/admin/server.php +++ b/resources/lang/en/admin/server.php @@ -16,7 +16,7 @@ return [ 'default_allocation_not_found' => 'The requested default allocation was not found in this server\'s allocations.', ], 'alerts' => [ - 'startup_changed' => 'The startup configuration for this server has been updated. If this server\'s nest or egg was changed a reinstall will be occuring now.', + 'startup_changed' => 'The startup configuration for this server has been updated. If this server\'s nest or egg was changed a reinstall will be occurring now.', 'server_deleted' => 'Server has successfully been deleted from the system.', 'server_created' => 'Server was successfully created on the panel. Please allow the daemon a few minutes to completely install this server.', 'build_updated' => 'The build details for this server have been updated. Some changes may require a restart to take effect.', diff --git a/resources/lang/en/base.php b/resources/lang/en/base.php index 51b18546d..2c0f6c62b 100644 --- a/resources/lang/en/base.php +++ b/resources/lang/en/base.php @@ -31,7 +31,7 @@ return [ 'index' => [ 'list' => 'Your Keys', 'header' => 'Account API', - 'header_sub' => 'Manage access keys that allow you to perform actions aganist the panel.', + 'header_sub' => 'Manage access keys that allow you to perform actions against the panel.', 'create_new' => 'Create New API key', 'keypair_created' => 'An API key has been successfully generated and is listed below.', ], @@ -45,7 +45,7 @@ return [ ], 'allowed_ips' => [ 'title' => 'Allowed IPs', - 'description' => 'Enter a line delimitated list of IPs that are allowed to access the API using this key. CIDR notation is allowed. Leave blank to allow any IP.', + 'description' => 'Enter a line delimited list of IPs that are allowed to access the API using this key. CIDR notation is allowed. Leave blank to allow any IP.', ], ], ], @@ -71,12 +71,12 @@ return [ 'header_sub' => 'Control active sessions and 2-Factor Authentication.', 'sessions' => 'Active Sessions', '2fa_header' => '2-Factor Authentication', - '2fa_token_help' => 'Enter the 2FA Token generated by your app (Google Authenticatior, Authy, etc.).', + '2fa_token_help' => 'Enter the 2FA Token generated by your app (Google Authenticator, Authy, etc.).', 'disable_2fa' => 'Disable 2-Factor Authentication', '2fa_enabled' => '2-Factor Authentication is enabled on this account and will be required in order to login to the panel. If you would like to disable 2FA, simply enter a valid token below and submit the form.', '2fa_disabled' => '2-Factor Authentication is disabled on your account! You should enable 2FA in order to add an extra level of protection on your account.', 'enable_2fa' => 'Enable 2-Factor Authentication', - '2fa_qr' => 'Confgure 2FA on Your Device', + '2fa_qr' => 'Configure 2FA on Your Device', '2fa_checkpoint_help' => 'Use the 2FA application on your phone to take a picture of the QR code to the left, or manually enter the code under it. Once you have done so, generate a token and enter it below.', '2fa_disable_error' => 'The 2FA token provided was not valid. Protection has not been disabled for this account.', ], diff --git a/resources/lang/en/command/messages.php b/resources/lang/en/command/messages.php index 1fd706a8b..68d172896 100644 --- a/resources/lang/en/command/messages.php +++ b/resources/lang/en/command/messages.php @@ -43,7 +43,7 @@ return [ 'server' => [ 'rebuild_failed' => 'Rebuild request for ":name" (#:id) on node ":node" failed with error: :message', 'power' => [ - 'confirm' => 'You are about to perform a :action aganist :count servers. Do you wish to continue?', + 'confirm' => 'You are about to perform a :action against :count servers. Do you wish to continue?', 'action_failed' => 'Power action request for ":name" (#:id) on node ":node" failed with error: :message', ], ], @@ -89,7 +89,7 @@ return [ 'using_redis' => 'You\'ve selected the Redis driver for one or more options, please provide valid connection information below. In most cases you can use the defaults provided unless you have modified your setup.', 'redis_host' => 'Redis Host', 'redis_password' => 'Redis Password', - 'redis_pass_help' => 'By default a Redis server instance has no password as it is running locally and inaccessable to the outside world. If this is the case, simply hit enter without entering a value.', + 'redis_pass_help' => 'By default a Redis server instance has no password as it is running locally and inaccessible to the outside world. If this is the case, simply hit enter without entering a value.', 'redis_port' => 'Redis Port', 'redis_pass_defined' => 'It seems a password is already defined for Redis, would you like to change it?', ], From c6c37e1b88439c34287cf3cf37fcdf6385fab0ca Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sun, 13 May 2018 10:24:07 -0400 Subject: [PATCH 13/66] occurred --- .../themes/pterodactyl/js/frontend/2fa-modal.js | 2 +- .../pterodactyl/js/frontend/files/src/actions.js | 16 ++++++++-------- .../pterodactyl/js/frontend/files/src/index.js | 2 +- .../js/frontend/tasks/management-actions.js | 6 +++--- .../themes/pterodactyl/admin/api/index.blade.php | 2 +- .../admin/servers/view/database.blade.php | 4 ++-- .../themes/pterodactyl/base/api/index.blade.php | 2 +- .../pterodactyl/server/databases/index.blade.php | 4 ++-- .../server/settings/allocation.blade.php | 2 +- .../pterodactyl/server/users/index.blade.php | 2 +- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/public/themes/pterodactyl/js/frontend/2fa-modal.js b/public/themes/pterodactyl/js/frontend/2fa-modal.js index d542b377c..8de4ee539 100644 --- a/public/themes/pterodactyl/js/frontend/2fa-modal.js +++ b/public/themes/pterodactyl/js/frontend/2fa-modal.js @@ -44,7 +44,7 @@ var TwoFactorModal = (function () { }); $('#open2fa').modal('show'); }).fail(function (jqXHR) { - alert('An error occured while attempting to load the 2FA setup modal. Please try again.'); + alert('An error occurred while attempting to load the 2FA setup modal. Please try again.'); console.error(jqXHR); }); diff --git a/public/themes/pterodactyl/js/frontend/files/src/actions.js b/public/themes/pterodactyl/js/frontend/files/src/actions.js index 83db5cfad..d2d6f42e2 100644 --- a/public/themes/pterodactyl/js/frontend/files/src/actions.js +++ b/public/themes/pterodactyl/js/frontend/files/src/actions.js @@ -72,7 +72,7 @@ class ActionsClass { Files.list(); }).fail(jqXHR => { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } @@ -118,7 +118,7 @@ class ActionsClass { swal.close(); }).fail(jqXHR => { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } @@ -198,7 +198,7 @@ class ActionsClass { inputField.remove(); }).fail(jqXHR => { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } @@ -255,7 +255,7 @@ class ActionsClass { Files.list(); }).fail(jqXHR => { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } @@ -315,7 +315,7 @@ class ActionsClass { type: 'error', title: 'Whoops!', html: true, - text: 'An error occured while attempting to delete this file. Please try again.', + text: 'An error occurred while attempting to delete this file. Please try again.', }); }); }); @@ -433,7 +433,7 @@ class ActionsClass { type: 'error', title: 'Whoops!', html: true, - text: 'An error occured while attempting to delete these files. Please try again.', + text: 'An error occurred while attempting to delete these files. Please try again.', }); }); }); @@ -476,7 +476,7 @@ class ActionsClass { Files.list(compPath); }).fail(jqXHR => { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } @@ -516,7 +516,7 @@ class ActionsClass { }); }).fail(jqXHR => { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } diff --git a/public/themes/pterodactyl/js/frontend/files/src/index.js b/public/themes/pterodactyl/js/frontend/files/src/index.js index b407c0f0b..a27d40306 100644 --- a/public/themes/pterodactyl/js/frontend/files/src/index.js +++ b/public/themes/pterodactyl/js/frontend/files/src/index.js @@ -71,7 +71,7 @@ class FileManager { swal({ type: 'error', title: 'File Error', - text: jqXHR.responseJSON.errors[0].detail || 'An error occured while attempting to process this request. Please try again.', + text: jqXHR.responseJSON.errors[0].detail || 'An error occurred while attempting to process this request. Please try again.', }); console.error(jqXHR); }); diff --git a/public/themes/pterodactyl/js/frontend/tasks/management-actions.js b/public/themes/pterodactyl/js/frontend/tasks/management-actions.js index 3c344a971..857c32cfa 100644 --- a/public/themes/pterodactyl/js/frontend/tasks/management-actions.js +++ b/public/themes/pterodactyl/js/frontend/tasks/management-actions.js @@ -54,7 +54,7 @@ $(document).ready(function () { swal({ type: 'error', title: 'Whoops!', - text: 'An error occured while attempting to delete this schedule.' + text: 'An error occurred while attempting to delete this schedule.' }); }); }); @@ -93,7 +93,7 @@ $(document).ready(function () { swal({ type: 'error', title: 'Whoops!', - text: 'An error occured while attempting to trigger this schedule.' + text: 'An error occurred while attempting to trigger this schedule.' }); }); }); @@ -136,7 +136,7 @@ $(document).ready(function () { swal({ type: 'error', title: 'Whoops!', - text: 'An error occured while attempting to toggle this schedule.' + text: 'An error occurred while attempting to toggle this schedule.' }); }); }); diff --git a/resources/themes/pterodactyl/admin/api/index.blade.php b/resources/themes/pterodactyl/admin/api/index.blade.php index ece51699f..9abcc2003 100644 --- a/resources/themes/pterodactyl/admin/api/index.blade.php +++ b/resources/themes/pterodactyl/admin/api/index.blade.php @@ -93,7 +93,7 @@ swal({ type: 'error', title: 'Whoops!', - text: 'An error occured while attempting to revoke this key.' + text: 'An error occurred while attempting to revoke this key.' }); }); }); diff --git a/resources/themes/pterodactyl/admin/servers/view/database.blade.php b/resources/themes/pterodactyl/admin/servers/view/database.blade.php index 6c556137d..9b7c81077 100644 --- a/resources/themes/pterodactyl/admin/servers/view/database.blade.php +++ b/resources/themes/pterodactyl/admin/servers/view/database.blade.php @@ -141,7 +141,7 @@ swal({ type: 'error', title: 'Whoops!', - text: (typeof jqXHR.responseJSON.error !== 'undefined') ? jqXHR.responseJSON.error : 'An error occured while processing this request.' + text: (typeof jqXHR.responseJSON.error !== 'undefined') ? jqXHR.responseJSON.error : 'An error occurred while processing this request.' }); }); }); @@ -163,7 +163,7 @@ }); }).fail(function(jqXHR, textStatus, errorThrown) { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } diff --git a/resources/themes/pterodactyl/base/api/index.blade.php b/resources/themes/pterodactyl/base/api/index.blade.php index 24a717347..99e5a1ca2 100644 --- a/resources/themes/pterodactyl/base/api/index.blade.php +++ b/resources/themes/pterodactyl/base/api/index.blade.php @@ -113,7 +113,7 @@ swal({ type: 'error', title: 'Whoops!', - text: 'An error occured while attempting to revoke this key.' + text: 'An error occurred while attempting to revoke this key.' }); }); }); diff --git a/resources/themes/pterodactyl/server/databases/index.blade.php b/resources/themes/pterodactyl/server/databases/index.blade.php index fb618b64c..d7b475ac6 100644 --- a/resources/themes/pterodactyl/server/databases/index.blade.php +++ b/resources/themes/pterodactyl/server/databases/index.blade.php @@ -148,7 +148,7 @@ block.parent().parent().find('[data-attr="set-password"]').html(data.password); }).fail(function(jqXHR) { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } @@ -188,7 +188,7 @@ swal({ type: 'error', title: 'Whoops!', - text: (typeof jqXHR.responseJSON.error !== 'undefined') ? jqXHR.responseJSON.error : 'An error occured while processing this request.' + text: (typeof jqXHR.responseJSON.error !== 'undefined') ? jqXHR.responseJSON.error : 'An error occurred while processing this request.' }); }); }); diff --git a/resources/themes/pterodactyl/server/settings/allocation.blade.php b/resources/themes/pterodactyl/server/settings/allocation.blade.php index 4c7d7661d..cc1952401 100644 --- a/resources/themes/pterodactyl/server/settings/allocation.blade.php +++ b/resources/themes/pterodactyl/server/settings/allocation.blade.php @@ -103,7 +103,7 @@ self.removeClass('btn-default').addClass('btn-success disabled').html('{{ trans('strings.primary') }}'); }).fail(function(jqXHR) { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } diff --git a/resources/themes/pterodactyl/server/users/index.blade.php b/resources/themes/pterodactyl/server/users/index.blade.php index 1cb88233f..3d08e590d 100644 --- a/resources/themes/pterodactyl/server/users/index.blade.php +++ b/resources/themes/pterodactyl/server/users/index.blade.php @@ -114,7 +114,7 @@ }); }).fail(function (jqXHR) { console.error(jqXHR); - var error = 'An error occured while trying to process this request.'; + var error = 'An error occurred while trying to process this request.'; if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') { error = jqXHR.responseJSON.error; } From 608ad33d319a60150ff0a637f4483b46a5aa0122 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sun, 13 May 2018 10:34:09 -0400 Subject: [PATCH 14/66] Spellcheck themes --- resources/themes/pterodactyl/admin/eggs/new.blade.php | 8 ++++---- resources/themes/pterodactyl/admin/eggs/scripts.blade.php | 2 +- .../themes/pterodactyl/admin/eggs/variables.blade.php | 4 ++-- resources/themes/pterodactyl/admin/eggs/view.blade.php | 4 ++-- resources/themes/pterodactyl/admin/nests/index.blade.php | 2 +- resources/themes/pterodactyl/admin/nests/new.blade.php | 2 +- resources/themes/pterodactyl/admin/nests/view.blade.php | 2 +- resources/themes/pterodactyl/admin/nodes/new.blade.php | 6 +++--- .../themes/pterodactyl/admin/nodes/view/index.blade.php | 2 +- .../pterodactyl/admin/nodes/view/settings.blade.php | 2 +- resources/themes/pterodactyl/admin/packs/modal.blade.php | 2 +- resources/themes/pterodactyl/admin/packs/new.blade.php | 2 +- resources/themes/pterodactyl/admin/packs/view.blade.php | 2 +- resources/themes/pterodactyl/admin/servers/new.blade.php | 2 +- .../themes/pterodactyl/admin/servers/view/build.blade.php | 2 +- .../pterodactyl/admin/servers/view/startup.blade.php | 6 +++--- .../themes/pterodactyl/admin/settings/index.blade.php | 2 +- resources/themes/pterodactyl/admin/users/new.blade.php | 2 +- resources/themes/pterodactyl/admin/users/view.blade.php | 2 +- 19 files changed, 28 insertions(+), 28 deletions(-) diff --git a/resources/themes/pterodactyl/admin/eggs/new.blade.php b/resources/themes/pterodactyl/admin/eggs/new.blade.php index 8059363f4..474d989a7 100644 --- a/resources/themes/pterodactyl/admin/eggs/new.blade.php +++ b/resources/themes/pterodactyl/admin/eggs/new.blade.php @@ -37,13 +37,13 @@ @endforeach -

    Think of a Nest as a category. You can put multiple Eggs in a nest, but consider putting only Eggs that are related to eachother in each Nest.

    +

    Think of a Nest as a category. You can put multiple Eggs in a nest, but consider putting only Eggs that are related to each other in each Nest.

    -

    A simple, human-readable name to use as an identifier for this Egg. This is what users will see as thier gameserver type.

    +

    A simple, human-readable name to use as an identifier for this Egg. This is what users will see as their game server type.

    @@ -60,7 +60,7 @@
    -

    The default statup command that should be used for new servers created with this Egg. You can change this per-server as needed.

    +

    The default startup command that should be used for new servers created with this Egg. You can change this per-server as needed.

    @@ -76,7 +76,7 @@
    -

    All fields are required unless you select a seperate option from the 'Copy Settings From' dropdown, in which case fields may be left blank to use the values from that option.

    +

    All fields are required unless you select a separate option from the 'Copy Settings From' dropdown, in which case fields may be left blank to use the values from that option.

    diff --git a/resources/themes/pterodactyl/admin/eggs/scripts.blade.php b/resources/themes/pterodactyl/admin/eggs/scripts.blade.php index 44252b264..55c6f1b9b 100644 --- a/resources/themes/pterodactyl/admin/eggs/scripts.blade.php +++ b/resources/themes/pterodactyl/admin/eggs/scripts.blade.php @@ -41,7 +41,7 @@ @if(! is_null($egg->copyFrom))
    - This service option is copying installation scripts and containe options from {{ $egg->copyFrom->name }}. Any changes you make to this script will not apply unless you select "None" from the dropdown box below. + This service option is copying installation scripts and container options from {{ $egg->copyFrom->name }}. Any changes you make to this script will not apply unless you select "None" from the dropdown box below.
    @endif diff --git a/resources/themes/pterodactyl/admin/eggs/variables.blade.php b/resources/themes/pterodactyl/admin/eggs/variables.blade.php index baf72f530..f49886ee5 100644 --- a/resources/themes/pterodactyl/admin/eggs/variables.blade.php +++ b/resources/themes/pterodactyl/admin/eggs/variables.blade.php @@ -68,7 +68,7 @@
    -

    This variable can be accessed in the statup command by using {{ $variable->env_variable }}.

    +

    This variable can be accessed in the startup command by using {{ $variable->env_variable }}.

    @@ -121,7 +121,7 @@
    -

    This variable can be accessed in the statup command by entering @{{environment variable value}}.

    +

    This variable can be accessed in the startup command by entering @{{environment variable value}}.

    diff --git a/resources/themes/pterodactyl/admin/eggs/view.blade.php b/resources/themes/pterodactyl/admin/eggs/view.blade.php index 9c91627e5..715f749e0 100644 --- a/resources/themes/pterodactyl/admin/eggs/view.blade.php +++ b/resources/themes/pterodactyl/admin/eggs/view.blade.php @@ -101,7 +101,7 @@
    -

    The default statup command that should be used for new servers using this Egg.

    +

    The default startup command that should be used for new servers using this Egg.

    @@ -118,7 +118,7 @@

    The following configuration options should not be edited unless you understand how this system works. If wrongly modified it is possible for the daemon to break.

    -

    All fields are required unless you select a seperate option from the 'Copy Settings From' dropdown, in which case fields may be left blank to use the values from that Egg.

    +

    All fields are required unless you select a separate option from the 'Copy Settings From' dropdown, in which case fields may be left blank to use the values from that Egg.

    diff --git a/resources/themes/pterodactyl/admin/nests/index.blade.php b/resources/themes/pterodactyl/admin/nests/index.blade.php index 9f9c1531c..3c726964b 100644 --- a/resources/themes/pterodactyl/admin/nests/index.blade.php +++ b/resources/themes/pterodactyl/admin/nests/index.blade.php @@ -21,7 +21,7 @@
    - Eggs are a powerful feature of Pterodactyl Panel that allow for extreme flexibility and configuration. Please note that while powerful, modifing an egg wrongly can very easily brick your servers and cause more problems. Please avoid editing our default eggs — those provided by support@pterodactyl.io — unless you are absolutely sure of what you are doing. + Eggs are a powerful feature of Pterodactyl Panel that allow for extreme flexibility and configuration. Please note that while powerful, modifying an egg wrongly can very easily brick your servers and cause more problems. Please avoid editing our default eggs — those provided by support@pterodactyl.io — unless you are absolutely sure of what you are doing.
    diff --git a/resources/themes/pterodactyl/admin/nests/new.blade.php b/resources/themes/pterodactyl/admin/nests/new.blade.php index ed7fa3cdd..a93911be7 100644 --- a/resources/themes/pterodactyl/admin/nests/new.blade.php +++ b/resources/themes/pterodactyl/admin/nests/new.blade.php @@ -31,7 +31,7 @@
    -

    This should be a descriptive category name that emcompasses all of the eggs within the nest.

    +

    This should be a descriptive category name that encompasses all of the eggs within the nest.

    diff --git a/resources/themes/pterodactyl/admin/nests/view.blade.php b/resources/themes/pterodactyl/admin/nests/view.blade.php index fe1e49462..d54155e58 100644 --- a/resources/themes/pterodactyl/admin/nests/view.blade.php +++ b/resources/themes/pterodactyl/admin/nests/view.blade.php @@ -28,7 +28,7 @@
    -

    This should be a descriptive category name that emcompasses all of the options within the service.

    +

    This should be a descriptive category name that encompasses all of the options within the service.

    diff --git a/resources/themes/pterodactyl/admin/nodes/new.blade.php b/resources/themes/pterodactyl/admin/nodes/new.blade.php index 0064ed899..94ecb609f 100644 --- a/resources/themes/pterodactyl/admin/nodes/new.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/new.blade.php @@ -126,7 +126,7 @@
    -

    Enter the total amount of memory avaliable for new servers. If you would like to allow overallocation of memory enter the percentage that you want to allow. To disable checking for overallocation enter -1 into the field. Entering 0 will prevent creating new servers if it would put the node over the limit.

    +

    Enter the total amount of memory available for new servers. If you would like to allow overallocation of memory enter the percentage that you want to allow. To disable checking for overallocation enter -1 into the field. Entering 0 will prevent creating new servers if it would put the node over the limit.

    @@ -145,7 +145,7 @@
    -

    Enter the total amount of disk space avaliable for new servers. If you would like to allow overallocation of disk space enter the percentage that you want to allow. To disable checking for overallocation enter -1 into the field. Entering 0 will prevent creating new servers if it would put the node over the limit.

    +

    Enter the total amount of disk space available for new servers. If you would like to allow overallocation of disk space enter the percentage that you want to allow. To disable checking for overallocation enter -1 into the field. Entering 0 will prevent creating new servers if it would put the node over the limit.

    @@ -158,7 +158,7 @@
    -

    The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server. Do not use the same port that you have assigned for your physcial server's SSH process. If you will be running the daemon behind CloudFlare® you should set the daemon port to 8443 to allow websocket proxying over SSL.

    +

    The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server. Do not use the same port that you have assigned for your physical server's SSH process. If you will be running the daemon behind CloudFlare® you should set the daemon port to 8443 to allow websocket proxying over SSL.

    diff --git a/resources/themes/pterodactyl/admin/nodes/view/index.blade.php b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php index 76a2ca627..9f385c9d8 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/index.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php @@ -76,7 +76,7 @@

    Delete Node

    -

    Deleting a node is a irreversable action and will immediately remove this node from the panel. There must be no servers associated with this node in order to continue.

    +

    Deleting a node is a irreversible action and will immediately remove this node from the panel. There must be no servers associated with this node in order to continue.

    -

    The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server. Do not use the same port that you have assigned for your physcial server's SSH process.

    +

    The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server. Do not use the same port that you have assigned for your physical server's SSH process.

    diff --git a/resources/themes/pterodactyl/admin/packs/modal.blade.php b/resources/themes/pterodactyl/admin/packs/modal.blade.php index dbf2044e0..551e6fde2 100644 --- a/resources/themes/pterodactyl/admin/packs/modal.blade.php +++ b/resources/themes/pterodactyl/admin/packs/modal.blade.php @@ -20,7 +20,7 @@ @endforeach -

    The Egg that this pack is assocaited with. Only servers that are assigned this Egg will be able to access this pack.

    +

    The Egg that this pack is associated with. Only servers that are assigned this Egg will be able to access this pack.

    diff --git a/resources/themes/pterodactyl/admin/packs/new.blade.php b/resources/themes/pterodactyl/admin/packs/new.blade.php index 35acdb540..1595083e9 100644 --- a/resources/themes/pterodactyl/admin/packs/new.blade.php +++ b/resources/themes/pterodactyl/admin/packs/new.blade.php @@ -62,7 +62,7 @@ @endforeach -

    The option that this pack is assocaited with. Only servers that are assigned this option will be able to access this pack.

    +

    The option that this pack is associated with. Only servers that are assigned this option will be able to access this pack.

    diff --git a/resources/themes/pterodactyl/admin/packs/view.blade.php b/resources/themes/pterodactyl/admin/packs/view.blade.php index e530bc9c4..cba76304d 100644 --- a/resources/themes/pterodactyl/admin/packs/view.blade.php +++ b/resources/themes/pterodactyl/admin/packs/view.blade.php @@ -66,7 +66,7 @@ @endforeach -

    The option that this pack is assocaited with. Only servers that are assigned this option will be able to access this pack. This assigned option cannot be changed if servers are attached to this pack.

    +

    The option that this pack is associated with. Only servers that are assigned this option will be able to access this pack. This assigned option cannot be changed if servers are attached to this pack.

    diff --git a/resources/themes/pterodactyl/admin/servers/new.blade.php b/resources/themes/pterodactyl/admin/servers/new.blade.php index c4a39f9c7..39d7ee326 100644 --- a/resources/themes/pterodactyl/admin/servers/new.blade.php +++ b/resources/themes/pterodactyl/admin/servers/new.blade.php @@ -239,7 +239,7 @@
    -

    The following data replacers are avaliable for the startup command: @{{SERVER_MEMORY}}, @{{SERVER_IP}}, and @{{SERVER_PORT}}. They will be replaced with the allocated memory, server IP, and server port respectively.

    +

    The following data substitutes are available for the startup command: @{{SERVER_MEMORY}}, @{{SERVER_IP}}, and @{{SERVER_PORT}}. They will be replaced with the allocated memory, server IP, and server port respectively.

    diff --git a/resources/themes/pterodactyl/admin/servers/view/build.blade.php b/resources/themes/pterodactyl/admin/servers/view/build.blade.php index 8900bf90a..2c5a45b60 100644 --- a/resources/themes/pterodactyl/admin/servers/view/build.blade.php +++ b/resources/themes/pterodactyl/admin/servers/view/build.blade.php @@ -102,7 +102,7 @@
    -

    The total number of databases a user is allowed to create for this server. Leave blank to allow unlimmited.

    +

    The total number of databases a user is allowed to create for this server. Leave blank to allow unlimited.

    diff --git a/resources/themes/pterodactyl/admin/servers/view/startup.blade.php b/resources/themes/pterodactyl/admin/servers/view/startup.blade.php index 60bc6d530..6bb7a5cde 100644 --- a/resources/themes/pterodactyl/admin/servers/view/startup.blade.php +++ b/resources/themes/pterodactyl/admin/servers/view/startup.blade.php @@ -70,11 +70,11 @@

    - Changing any of the below values will result in the server processing a re-install command. The server will be stopped and will then proceede. - If you are changing the pack, exisiting data may be overwritten. If you would like the service scripts to not run, ensure the box is checked at the bottom. + Changing any of the below values will result in the server processing a re-install command. The server will be stopped and will then proceed. + If you are changing the pack, existing data may be overwritten. If you would like the service scripts to not run, ensure the box is checked at the bottom.

    - This is a destructive operation in many cases. This server will be stopped immediately in order for this action to proceede. + This is a destructive operation in many cases. This server will be stopped immediately in order for this action to proceed.

    diff --git a/resources/themes/pterodactyl/admin/settings/index.blade.php b/resources/themes/pterodactyl/admin/settings/index.blade.php index 62ef09631..489646dc9 100644 --- a/resources/themes/pterodactyl/admin/settings/index.blade.php +++ b/resources/themes/pterodactyl/admin/settings/index.blade.php @@ -52,7 +52,7 @@
    - +
    @foreach($languages as $key => $value) diff --git a/resources/themes/pterodactyl/admin/users/view.blade.php b/resources/themes/pterodactyl/admin/users/view.blade.php index fa3b333d7..125719d9c 100644 --- a/resources/themes/pterodactyl/admin/users/view.blade.php +++ b/resources/themes/pterodactyl/admin/users/view.blade.php @@ -52,7 +52,7 @@
    - +
    \n \n `;\n\n nameBlock.html(attachEditor);\n const inputField = nameBlock.find('input');\n const inputLoader = nameBlock.find('.input-loader');\n\n inputField.focus();\n inputField.on('blur keydown', e => {\n // Save Field\n if (\n (e.type === 'keydown' && e.which === 27)\n || e.type === 'blur'\n || (e.type === 'keydown' && e.which === 13 && currentName === inputField.val())\n ) {\n if (!_.isEmpty(currentLink)) {\n nameBlock.html(currentLink);\n } else {\n nameBlock.html(currentName);\n }\n inputField.remove();\n ContextMenu.unbind().run();\n return;\n }\n\n if (e.type === 'keydown' && e.which !== 13) return;\n\n inputLoader.show();\n const currentPath = decodeURIComponent(nameBlock.data('path'));\n\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/rename`,\n timeout: 10000,\n data: JSON.stringify({\n from: `${currentPath}${currentName}`,\n to: `${currentPath}${inputField.val()}`,\n }),\n }).done(data => {\n nameBlock.attr('data-name', inputField.val());\n if (!_.isEmpty(currentLink)) {\n let newLink = currentLink.attr('href');\n if (nameBlock.parent().data('type') !== 'folder') {\n newLink = newLink.substr(0, newLink.lastIndexOf('/')) + '/' + inputField.val();\n }\n currentLink.attr('href', newLink);\n nameBlock.html(\n currentLink.html(inputField.val())\n );\n } else {\n nameBlock.html(inputField.val());\n }\n inputField.remove();\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occured while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n nameBlock.addClass('has-error').delay(2000).queue(() => {\n nameBlock.removeClass('has-error').dequeue();\n });\n inputField.popover({\n animation: true,\n placement: 'top',\n content: error,\n title: 'Save Error'\n }).popover('show');\n }).always(() => {\n inputLoader.remove();\n ContextMenu.unbind().run();\n });\n });\n }\n\n copy() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const currentName = decodeURIComponent(nameBlock.attr('data-name'));\n const currentPath = decodeURIComponent(nameBlock.data('path'));\n\n swal({\n type: 'input',\n title: 'Copy File',\n text: 'Please enter the new path for the copied file below.',\n showCancelButton: true,\n showConfirmButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true,\n inputValue: `${currentPath}${currentName}`,\n }, (val) => {\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/copy`,\n timeout: 10000,\n data: JSON.stringify({\n from: `${currentPath}${currentName}`,\n to: `${val}`,\n }),\n }).done(data => {\n swal({\n type: 'success',\n title: '',\n text: 'File successfully copied.'\n });\n Files.list();\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occured while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n swal({\n type: 'error',\n title: '',\n text: error,\n });\n });\n });\n }\n\n download() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const fileName = decodeURIComponent(nameBlock.attr('data-name'));\n const filePath = decodeURIComponent(nameBlock.data('path'));\n\n window.location = `/server/${Pterodactyl.server.uuidShort}/files/download/${filePath}${fileName}`;\n }\n\n delete() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const delPath = decodeURIComponent(nameBlock.data('path'));\n const delName = decodeURIComponent(nameBlock.data('name'));\n\n swal({\n type: 'warning',\n title: '',\n text: 'Are you sure you want to delete ' + delName + '? There is no reversing this action.',\n html: true,\n showCancelButton: true,\n showConfirmButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true\n }, () => {\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/delete`,\n timeout: 10000,\n data: JSON.stringify({\n items: [`${delPath}${delName}`]\n }),\n }).done(data => {\n nameBlock.parent().addClass('warning').delay(200).fadeOut();\n swal({\n type: 'success',\n title: 'File Deleted'\n });\n }).fail(jqXHR => {\n console.error(jqXHR);\n swal({\n type: 'error',\n title: 'Whoops!',\n html: true,\n text: 'An error occured while attempting to delete this file. Please try again.',\n });\n });\n });\n }\n\n toggleMassActions() {\n if ($('#file_listing input[type=\"checkbox\"]:checked').length) {\n $('#mass_actions').removeClass('disabled');\n } else {\n $('#mass_actions').addClass('disabled');\n }\n }\n\n toggleHighlight(event) {\n const parent = $(event.currentTarget);\n const item = $(event.currentTarget).find('input');\n\n if($(item).is(':checked')) {\n $(item).prop('checked', false);\n parent.removeClass('warning').delay(200);\n } else {\n $(item).prop('checked', true);\n parent.addClass('warning').delay(200);\n }\n }\n\n highlightAll(event) {\n let parent;\n const item = $(event.currentTarget).find('input');\n\n if($(item).is(':checked')) {\n $('#file_listing input[type=checkbox]').prop('checked', false);\n $('#file_listing input[data-action=\"addSelection\"]').each(function() {\n parent = $(this).closest('tr');\n parent.removeClass('warning').delay(200);\n });\n } else {\n $('#file_listing input[type=checkbox]').prop('checked', true);\n $('#file_listing input[data-action=\"addSelection\"]').each(function() {\n parent = $(this).closest('tr');\n parent.addClass('warning').delay(200);\n });\n }\n }\n\n deleteSelected() {\n let selectedItems = [];\n let selectedItemsElements = [];\n let parent;\n let nameBlock;\n let delLocation;\n\n $('#file_listing input[data-action=\"addSelection\"]:checked').each(function() {\n parent = $(this).closest('tr');\n nameBlock = $(parent).find('td[data-identifier=\"name\"]');\n delLocation = decodeURIComponent(nameBlock.data('path')) + decodeURIComponent(nameBlock.data('name'));\n\n selectedItems.push(delLocation);\n selectedItemsElements.push(parent);\n });\n\n if (selectedItems.length != 0)\n {\n let formattedItems = \"\";\n $.each(selectedItems, function(key, value) {\n formattedItems += (\"\" + value + \", \");\n })\n\n formattedItems = formattedItems.slice(0, -2);\n\n swal({\n type: 'warning',\n title: '',\n text: 'Are you sure you want to delete:' + formattedItems + '? There is no reversing this action.',\n html: true,\n showCancelButton: true,\n showConfirmButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true\n }, () => {\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/delete`,\n timeout: 10000,\n data: JSON.stringify({\n items: selectedItems\n }),\n }).done(data => {\n $('#file_listing input:checked').each(function() {\n $(this).prop('checked', false);\n });\n\n $.each(selectedItemsElements, function() {\n $(this).addClass('warning').delay(200).fadeOut();\n })\n\n swal({\n type: 'success',\n title: 'Files Deleted'\n });\n }).fail(jqXHR => {\n console.error(jqXHR);\n swal({\n type: 'error',\n title: 'Whoops!',\n html: true,\n text: 'An error occured while attempting to delete these files. Please try again.',\n });\n });\n });\n } else {\n swal({\n type: 'warning',\n title: '',\n text: 'Please select files/folders to delete.',\n });\n }\n }\n\n decompress() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const compPath = decodeURIComponent(nameBlock.data('path'));\n const compName = decodeURIComponent(nameBlock.data('name'));\n\n swal({\n title: ' Decompressing...',\n text: 'This might take a few seconds to complete.',\n html: true,\n allowOutsideClick: false,\n allowEscapeKey: false,\n showConfirmButton: false,\n });\n\n $.ajax({\n type: 'POST',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/decompress`,\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify({\n files: `${compPath}${compName}`\n })\n }).done(data => {\n swal.close();\n Files.list(compPath);\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occured while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n swal({\n type: 'error',\n title: 'Whoops!',\n html: true,\n text: error\n });\n });\n }\n\n compress() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const compPath = decodeURIComponent(nameBlock.data('path'));\n const compName = decodeURIComponent(nameBlock.data('name'));\n\n $.ajax({\n type: 'POST',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/compress`,\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify({\n files: `${compPath}${compName}`,\n to: compPath.toString()\n })\n }).done(data => {\n Files.list(compPath, err => {\n if (err) return;\n const fileListing = $('#file_listing').find(`[data-name=\"${data.saved_as}\"]`).parent();\n fileListing.addClass('success pulsate').delay(3000).queue(() => {\n fileListing.removeClass('success pulsate').dequeue();\n });\n });\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occured while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n swal({\n type: 'error',\n title: 'Whoops!',\n html: true,\n text: error\n });\n });\n }\n}\n","\"use strict\";\n\n// Copyright (c) 2015 - 2017 Dane Everitt \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\nclass ContextMenuClass {\n constructor() {\n this.activeLine = null;\n }\n\n run() {\n this.directoryClick();\n this.rightClick();\n }\n\n makeMenu(parent) {\n $(document).find('#fileOptionMenu').remove();\n if (!_.isNull(this.activeLine)) this.activeLine.removeClass('active');\n\n let newFilePath = $('#file_listing').data('current-dir');\n if (parent.data('type') === 'folder') {\n const nameBlock = parent.find('td[data-identifier=\"name\"]');\n const currentName = decodeURIComponent(nameBlock.attr('data-name'));\n const currentPath = decodeURIComponent(nameBlock.data('path'));\n newFilePath = `${currentPath}${currentName}`;\n }\n\n let buildMenu = '
      ';\n\n if (Pterodactyl.permissions.moveFiles) {\n buildMenu += '
    • Rename
    • \\\n
    • Move
    • ';\n }\n\n if (Pterodactyl.permissions.copyFiles) {\n buildMenu += '
    • Copy
    • ';\n }\n\n if (Pterodactyl.permissions.compressFiles) {\n buildMenu += '
    • Compress
    • ';\n }\n\n if (Pterodactyl.permissions.decompressFiles) {\n buildMenu += '
    • Decompress
    • ';\n }\n\n if (Pterodactyl.permissions.createFiles) {\n buildMenu += '
    • \\\n
    • New File
    • \\\n
    • New Folder
    • ';\n }\n\n if (Pterodactyl.permissions.downloadFiles || Pterodactyl.permissions.deleteFiles) {\n buildMenu += '
    • ';\n }\n\n if (Pterodactyl.permissions.downloadFiles) {\n buildMenu += '
    • Download
    • ';\n }\n\n if (Pterodactyl.permissions.deleteFiles) {\n buildMenu += '
    • Delete
    • ';\n }\n\n buildMenu += '
    ';\n return buildMenu;\n }\n\n rightClick() {\n $('[data-action=\"toggleMenu\"]').on('mousedown', event => {\n event.preventDefault();\n if ($(document).find('#fileOptionMenu').is(':visible')) {\n $('body').trigger('click');\n return;\n }\n this.showMenu(event);\n });\n $('#file_listing > tbody td').on('contextmenu', event => {\n this.showMenu(event);\n });\n }\n\n showMenu(event) {\n const parent = $(event.target).closest('tr');\n const menu = $(this.makeMenu(parent));\n\n if (parent.data('type') === 'disabled') return;\n event.preventDefault();\n\n $(menu).appendTo('body');\n $(menu).data('invokedOn', $(event.target)).show().css({\n position: 'absolute',\n left: event.pageX - 150,\n top: event.pageY,\n });\n\n this.activeLine = parent;\n this.activeLine.addClass('active');\n\n // Handle Events\n const Actions = new ActionsClass(parent, menu);\n if (Pterodactyl.permissions.moveFiles) {\n $(menu).find('li[data-action=\"move\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.move();\n });\n $(menu).find('li[data-action=\"rename\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.rename();\n });\n }\n\n if (Pterodactyl.permissions.copyFiles) {\n $(menu).find('li[data-action=\"copy\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.copy();\n });\n }\n\n if (Pterodactyl.permissions.compressFiles) {\n if (parent.data('type') === 'folder') {\n $(menu).find('li[data-action=\"compress\"]').removeClass('hidden');\n }\n $(menu).find('li[data-action=\"compress\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.compress();\n });\n }\n\n if (Pterodactyl.permissions.decompressFiles) {\n if (_.without(['application/zip', 'application/gzip', 'application/x-gzip'], parent.data('mime')).length < 3) {\n $(menu).find('li[data-action=\"decompress\"]').removeClass('hidden');\n }\n $(menu).find('li[data-action=\"decompress\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.decompress();\n });\n }\n\n if (Pterodactyl.permissions.createFiles) {\n $(menu).find('li[data-action=\"folder\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.folder();\n });\n }\n\n if (Pterodactyl.permissions.downloadFiles) {\n if (parent.data('type') === 'file') {\n $(menu).find('li[data-action=\"download\"]').removeClass('hidden');\n }\n $(menu).find('li[data-action=\"download\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.download();\n });\n }\n\n if (Pterodactyl.permissions.deleteFiles) {\n $(menu).find('li[data-action=\"delete\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.delete();\n });\n }\n\n $(window).unbind().on('click', event => {\n if($(event.target).is('.disable-menu-hide')) {\n event.preventDefault();\n return;\n }\n $(menu).unbind().remove();\n if(!_.isNull(this.activeLine)) this.activeLine.removeClass('active');\n });\n }\n\n directoryClick() {\n $('a[data-action=\"directory-view\"]').on('click', function (event) {\n event.preventDefault();\n\n const path = $(this).parent().data('path') || '';\n const name = $(this).parent().data('name') || '';\n\n window.location.hash = encodeURIComponent(path + name);\n Files.list();\n });\n }\n}\n\nwindow.ContextMenu = new ContextMenuClass;\n","\"use strict\";\n\n// Copyright (c) 2015 - 2017 Dane Everitt \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\nclass FileManager {\n constructor() {\n this.list(this.decodeHash());\n }\n\n list(path, next) {\n if (_.isUndefined(path)) {\n path = this.decodeHash();\n }\n\n this.loader(true);\n $.ajax({\n type: 'POST',\n url: Pterodactyl.meta.directoryList,\n headers: {\n 'X-CSRF-Token': Pterodactyl.meta.csrftoken,\n },\n data: {\n directory: path,\n },\n }).done(data => {\n this.loader(false);\n $('#load_files').slideUp(10).html(data).slideDown(10, () => {\n ContextMenu.run();\n this.reloadFilesButton();\n this.addFolderButton();\n this.selectItem();\n this.selectAll();\n this.selectiveDeletion();\n this.selectRow();\n if (_.isFunction(next)) {\n return next();\n }\n });\n $('#internal_alert').slideUp();\n\n if (typeof Siofu === 'object') {\n Siofu.listenOnInput(document.getElementById(\"files_touch_target\"));\n }\n }).fail(jqXHR => {\n this.loader(false);\n if (_.isFunction(next)) {\n return next(new Error('Failed to load file listing.'));\n }\n\n if ((path !== '' && path !== '/') && jqXHR.status === 404) {\n return this.list('', next);\n }\n\n swal({\n type: 'error',\n title: 'File Error',\n text: jqXHR.responseJSON.errors[0].detail || 'An error occured while attempting to process this request. Please try again.',\n });\n console.error(jqXHR);\n });\n }\n\n loader(show) {\n if (show){\n $('.file-overlay').fadeIn(100);\n } else {\n $('.file-overlay').fadeOut(100);\n }\n }\n\n reloadFilesButton() {\n $('i[data-action=\"reload-files\"]').unbind().on('click', () => {\n $('i[data-action=\"reload-files\"]').addClass('fa-spin');\n this.list();\n });\n }\n\n selectItem() {\n $('[data-action=\"addSelection\"]').on('click', event => {\n event.preventDefault();\n });\n }\n\n selectAll() {\n $('[data-action=\"selectAll\"]').on('click', event => {\n event.preventDefault();\n });\n }\n\n selectiveDeletion() {\n $('[data-action=\"selective-deletion\"]').on('mousedown', event => {\n new ActionsClass().deleteSelected();\n });\n }\n\n addFolderButton() {\n $('[data-action=\"add-folder\"]').unbind().on('click', () => {\n new ActionsClass().folder($('#file_listing').data('current-dir') || '/');\n })\n }\n\n selectRow() {\n $('#file_listing tr').on('mousedown', event => {\n if (event.which === 1) {\n if ($(event.target).is('th') || $(event.target).is('input[data-action=\"selectAll\"]')) {\n new ActionsClass().highlightAll(event);\n } else if ($(event.target).is('td') || $(event.target).is('input[data-action=\"addSelection\"]')) {\n new ActionsClass().toggleHighlight(event);\n }\n\n new ActionsClass().toggleMassActions();\n }\n });\n }\n\n decodeHash() {\n return decodeURIComponent(window.location.hash.substring(1));\n }\n\n}\n\nwindow.Files = new FileManager;\n"]} \ No newline at end of file +{"version":3,"sources":["src/actions.js","src/contextmenu.js","src/index.js"],"names":[],"mappings":"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","file":"filemanager.min.js","sourcesContent":["\"use strict\";\n\n// Copyright (c) 2015 - 2017 Dane Everitt \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\nclass ActionsClass {\n constructor(element, menu) {\n this.element = element;\n this.menu = menu;\n }\n\n destroy() {\n this.element = undefined;\n }\n\n folder(path) {\n let inputValue\n if (path) {\n inputValue = path\n } else {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const currentName = decodeURIComponent(nameBlock.data('name'));\n const currentPath = decodeURIComponent(nameBlock.data('path'));\n\n if ($(this.element).data('type') === 'file') {\n inputValue = currentPath;\n } else {\n inputValue = `${currentPath}${currentName}/`;\n }\n }\n\n swal({\n type: 'input',\n title: 'Create Folder',\n text: 'Please enter the path and folder name below.',\n showCancelButton: true,\n showConfirmButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true,\n inputValue: inputValue\n }, (val) => {\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/folder`,\n timeout: 10000,\n data: JSON.stringify({\n path: val,\n }),\n }).done(data => {\n swal.close();\n Files.list();\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occurred while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n swal({\n type: 'error',\n title: '',\n text: error,\n });\n });\n });\n }\n\n move() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const currentName = decodeURIComponent(nameBlock.attr('data-name'));\n const currentPath = decodeURIComponent(nameBlock.data('path'));\n\n swal({\n type: 'input',\n title: 'Move File',\n text: 'Please enter the new path for the file below.',\n showCancelButton: true,\n showConfirmButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true,\n inputValue: `${currentPath}${currentName}`,\n }, (val) => {\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/move`,\n timeout: 10000,\n data: JSON.stringify({\n from: `${currentPath}${currentName}`,\n to: `${val}`,\n }),\n }).done(data => {\n nameBlock.parent().addClass('warning').delay(200).fadeOut();\n swal.close();\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occurred while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n swal({\n type: 'error',\n title: '',\n text: error,\n });\n });\n });\n\n }\n\n rename() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const currentLink = nameBlock.find('a');\n const currentName = decodeURIComponent(nameBlock.attr('data-name'));\n const attachEditor = `\n \n \n `;\n\n nameBlock.html(attachEditor);\n const inputField = nameBlock.find('input');\n const inputLoader = nameBlock.find('.input-loader');\n\n inputField.focus();\n inputField.on('blur keydown', e => {\n // Save Field\n if (\n (e.type === 'keydown' && e.which === 27)\n || e.type === 'blur'\n || (e.type === 'keydown' && e.which === 13 && currentName === inputField.val())\n ) {\n if (!_.isEmpty(currentLink)) {\n nameBlock.html(currentLink);\n } else {\n nameBlock.html(currentName);\n }\n inputField.remove();\n ContextMenu.unbind().run();\n return;\n }\n\n if (e.type === 'keydown' && e.which !== 13) return;\n\n inputLoader.show();\n const currentPath = decodeURIComponent(nameBlock.data('path'));\n\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/rename`,\n timeout: 10000,\n data: JSON.stringify({\n from: `${currentPath}${currentName}`,\n to: `${currentPath}${inputField.val()}`,\n }),\n }).done(data => {\n nameBlock.attr('data-name', inputField.val());\n if (!_.isEmpty(currentLink)) {\n let newLink = currentLink.attr('href');\n if (nameBlock.parent().data('type') !== 'folder') {\n newLink = newLink.substr(0, newLink.lastIndexOf('/')) + '/' + inputField.val();\n }\n currentLink.attr('href', newLink);\n nameBlock.html(\n currentLink.html(inputField.val())\n );\n } else {\n nameBlock.html(inputField.val());\n }\n inputField.remove();\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occurred while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n nameBlock.addClass('has-error').delay(2000).queue(() => {\n nameBlock.removeClass('has-error').dequeue();\n });\n inputField.popover({\n animation: true,\n placement: 'top',\n content: error,\n title: 'Save Error'\n }).popover('show');\n }).always(() => {\n inputLoader.remove();\n ContextMenu.unbind().run();\n });\n });\n }\n\n copy() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const currentName = decodeURIComponent(nameBlock.attr('data-name'));\n const currentPath = decodeURIComponent(nameBlock.data('path'));\n\n swal({\n type: 'input',\n title: 'Copy File',\n text: 'Please enter the new path for the copied file below.',\n showCancelButton: true,\n showConfirmButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true,\n inputValue: `${currentPath}${currentName}`,\n }, (val) => {\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/copy`,\n timeout: 10000,\n data: JSON.stringify({\n from: `${currentPath}${currentName}`,\n to: `${val}`,\n }),\n }).done(data => {\n swal({\n type: 'success',\n title: '',\n text: 'File successfully copied.'\n });\n Files.list();\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occurred while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n swal({\n type: 'error',\n title: '',\n text: error,\n });\n });\n });\n }\n\n download() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const fileName = decodeURIComponent(nameBlock.attr('data-name'));\n const filePath = decodeURIComponent(nameBlock.data('path'));\n\n window.location = `/server/${Pterodactyl.server.uuidShort}/files/download/${filePath}${fileName}`;\n }\n\n delete() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const delPath = decodeURIComponent(nameBlock.data('path'));\n const delName = decodeURIComponent(nameBlock.data('name'));\n\n swal({\n type: 'warning',\n title: '',\n text: 'Are you sure you want to delete ' + delName + '?',\n html: true,\n showCancelButton: true,\n showConfirmButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true\n }, () => {\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/delete`,\n timeout: 10000,\n data: JSON.stringify({\n items: [`${delPath}${delName}`]\n }),\n }).done(data => {\n nameBlock.parent().addClass('warning').delay(200).fadeOut();\n swal({\n type: 'success',\n title: 'File Deleted'\n });\n }).fail(jqXHR => {\n console.error(jqXHR);\n swal({\n type: 'error',\n title: 'Whoops!',\n html: true,\n text: 'An error occurred while attempting to delete this file. Please try again.',\n });\n });\n });\n }\n\n toggleMassActions() {\n if ($('#file_listing input[type=\"checkbox\"]:checked').length) {\n $('#mass_actions').removeClass('disabled');\n } else {\n $('#mass_actions').addClass('disabled');\n }\n }\n\n toggleHighlight(event) {\n const parent = $(event.currentTarget);\n const item = $(event.currentTarget).find('input');\n\n if($(item).is(':checked')) {\n $(item).prop('checked', false);\n parent.removeClass('warning').delay(200);\n } else {\n $(item).prop('checked', true);\n parent.addClass('warning').delay(200);\n }\n }\n\n highlightAll(event) {\n let parent;\n const item = $(event.currentTarget).find('input');\n\n if($(item).is(':checked')) {\n $('#file_listing input[type=checkbox]').prop('checked', false);\n $('#file_listing input[data-action=\"addSelection\"]').each(function() {\n parent = $(this).closest('tr');\n parent.removeClass('warning').delay(200);\n });\n } else {\n $('#file_listing input[type=checkbox]').prop('checked', true);\n $('#file_listing input[data-action=\"addSelection\"]').each(function() {\n parent = $(this).closest('tr');\n parent.addClass('warning').delay(200);\n });\n }\n }\n\n deleteSelected() {\n let selectedItems = [];\n let selectedItemsElements = [];\n let parent;\n let nameBlock;\n let delLocation;\n\n $('#file_listing input[data-action=\"addSelection\"]:checked').each(function() {\n parent = $(this).closest('tr');\n nameBlock = $(parent).find('td[data-identifier=\"name\"]');\n delLocation = decodeURIComponent(nameBlock.data('path')) + decodeURIComponent(nameBlock.data('name'));\n\n selectedItems.push(delLocation);\n selectedItemsElements.push(parent);\n });\n\n if (selectedItems.length != 0)\n {\n let formattedItems = \"\";\n let i = 0;\n $.each(selectedItems, function(key, value) {\n formattedItems += (\"\" + value + \", \");\n i++;\n return i < 5;\n });\n\n formattedItems = formattedItems.slice(0, -2);\n if (selectedItems.length > 5) {\n formattedItems += ', and ' + (selectedItems.length - 5) + ' other(s)';\n }\n\n swal({\n type: 'warning',\n title: '',\n text: 'Are you sure you want to delete the following files: ' + formattedItems + '?',\n html: true,\n showCancelButton: true,\n showConfirmButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true\n }, () => {\n $.ajax({\n type: 'POST',\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/delete`,\n timeout: 10000,\n data: JSON.stringify({\n items: selectedItems\n }),\n }).done(data => {\n $('#file_listing input:checked').each(function() {\n $(this).prop('checked', false);\n });\n\n $.each(selectedItemsElements, function() {\n $(this).addClass('warning').delay(200).fadeOut();\n })\n\n swal({\n type: 'success',\n title: 'Files Deleted'\n });\n }).fail(jqXHR => {\n console.error(jqXHR);\n swal({\n type: 'error',\n title: 'Whoops!',\n html: true,\n text: 'An error occurred while attempting to delete these files. Please try again.',\n });\n });\n });\n } else {\n swal({\n type: 'warning',\n title: '',\n text: 'Please select files/folders to delete.',\n });\n }\n }\n\n decompress() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const compPath = decodeURIComponent(nameBlock.data('path'));\n const compName = decodeURIComponent(nameBlock.data('name'));\n\n swal({\n title: ' Decompressing...',\n text: 'This might take a few seconds to complete.',\n html: true,\n allowOutsideClick: false,\n allowEscapeKey: false,\n showConfirmButton: false,\n });\n\n $.ajax({\n type: 'POST',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/decompress`,\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify({\n files: `${compPath}${compName}`\n })\n }).done(data => {\n swal.close();\n Files.list(compPath);\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occurred while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n swal({\n type: 'error',\n title: 'Whoops!',\n html: true,\n text: error\n });\n });\n }\n\n compress() {\n const nameBlock = $(this.element).find('td[data-identifier=\"name\"]');\n const compPath = decodeURIComponent(nameBlock.data('path'));\n const compName = decodeURIComponent(nameBlock.data('name'));\n\n $.ajax({\n type: 'POST',\n url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/compress`,\n headers: {\n 'X-Access-Token': Pterodactyl.server.daemonSecret,\n 'X-Access-Server': Pterodactyl.server.uuid,\n },\n contentType: 'application/json; charset=utf-8',\n data: JSON.stringify({\n files: `${compPath}${compName}`,\n to: compPath.toString()\n })\n }).done(data => {\n Files.list(compPath, err => {\n if (err) return;\n const fileListing = $('#file_listing').find(`[data-name=\"${data.saved_as}\"]`).parent();\n fileListing.addClass('success pulsate').delay(3000).queue(() => {\n fileListing.removeClass('success pulsate').dequeue();\n });\n });\n }).fail(jqXHR => {\n console.error(jqXHR);\n var error = 'An error occurred while trying to process this request.';\n if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {\n error = jqXHR.responseJSON.error;\n }\n swal({\n type: 'error',\n title: 'Whoops!',\n html: true,\n text: error\n });\n });\n }\n}\n","\"use strict\";\n\n// Copyright (c) 2015 - 2017 Dane Everitt \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\nclass ContextMenuClass {\n constructor() {\n this.activeLine = null;\n }\n\n run() {\n this.directoryClick();\n this.rightClick();\n }\n\n makeMenu(parent) {\n $(document).find('#fileOptionMenu').remove();\n if (!_.isNull(this.activeLine)) this.activeLine.removeClass('active');\n\n let newFilePath = $('#file_listing').data('current-dir');\n if (parent.data('type') === 'folder') {\n const nameBlock = parent.find('td[data-identifier=\"name\"]');\n const currentName = decodeURIComponent(nameBlock.attr('data-name'));\n const currentPath = decodeURIComponent(nameBlock.data('path'));\n newFilePath = `${currentPath}${currentName}`;\n }\n\n let buildMenu = '
      ';\n\n if (Pterodactyl.permissions.moveFiles) {\n buildMenu += '
    • Rename
    • \\\n
    • Move
    • ';\n }\n\n if (Pterodactyl.permissions.copyFiles) {\n buildMenu += '
    • Copy
    • ';\n }\n\n if (Pterodactyl.permissions.compressFiles) {\n buildMenu += '
    • Compress
    • ';\n }\n\n if (Pterodactyl.permissions.decompressFiles) {\n buildMenu += '
    • Decompress
    • ';\n }\n\n if (Pterodactyl.permissions.createFiles) {\n buildMenu += '
    • \\\n
    • New File
    • \\\n
    • New Folder
    • ';\n }\n\n if (Pterodactyl.permissions.downloadFiles || Pterodactyl.permissions.deleteFiles) {\n buildMenu += '
    • ';\n }\n\n if (Pterodactyl.permissions.downloadFiles) {\n buildMenu += '
    • Download
    • ';\n }\n\n if (Pterodactyl.permissions.deleteFiles) {\n buildMenu += '
    • Delete
    • ';\n }\n\n buildMenu += '
    ';\n return buildMenu;\n }\n\n rightClick() {\n $('[data-action=\"toggleMenu\"]').on('mousedown', event => {\n event.preventDefault();\n if ($(document).find('#fileOptionMenu').is(':visible')) {\n $('body').trigger('click');\n return;\n }\n this.showMenu(event);\n });\n $('#file_listing > tbody td').on('contextmenu', event => {\n this.showMenu(event);\n });\n }\n\n showMenu(event) {\n const parent = $(event.target).closest('tr');\n const menu = $(this.makeMenu(parent));\n\n if (parent.data('type') === 'disabled') return;\n event.preventDefault();\n\n $(menu).appendTo('body');\n $(menu).data('invokedOn', $(event.target)).show().css({\n position: 'absolute',\n left: event.pageX - 150,\n top: event.pageY,\n });\n\n this.activeLine = parent;\n this.activeLine.addClass('active');\n\n // Handle Events\n const Actions = new ActionsClass(parent, menu);\n if (Pterodactyl.permissions.moveFiles) {\n $(menu).find('li[data-action=\"move\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.move();\n });\n $(menu).find('li[data-action=\"rename\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.rename();\n });\n }\n\n if (Pterodactyl.permissions.copyFiles) {\n $(menu).find('li[data-action=\"copy\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.copy();\n });\n }\n\n if (Pterodactyl.permissions.compressFiles) {\n if (parent.data('type') === 'folder') {\n $(menu).find('li[data-action=\"compress\"]').removeClass('hidden');\n }\n $(menu).find('li[data-action=\"compress\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.compress();\n });\n }\n\n if (Pterodactyl.permissions.decompressFiles) {\n if (_.without(['application/zip', 'application/gzip', 'application/x-gzip'], parent.data('mime')).length < 3) {\n $(menu).find('li[data-action=\"decompress\"]').removeClass('hidden');\n }\n $(menu).find('li[data-action=\"decompress\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.decompress();\n });\n }\n\n if (Pterodactyl.permissions.createFiles) {\n $(menu).find('li[data-action=\"folder\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.folder();\n });\n }\n\n if (Pterodactyl.permissions.downloadFiles) {\n if (parent.data('type') === 'file') {\n $(menu).find('li[data-action=\"download\"]').removeClass('hidden');\n }\n $(menu).find('li[data-action=\"download\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.download();\n });\n }\n\n if (Pterodactyl.permissions.deleteFiles) {\n $(menu).find('li[data-action=\"delete\"]').unbind().on('click', e => {\n e.preventDefault();\n Actions.delete();\n });\n }\n\n $(window).unbind().on('click', event => {\n if($(event.target).is('.disable-menu-hide')) {\n event.preventDefault();\n return;\n }\n $(menu).unbind().remove();\n if(!_.isNull(this.activeLine)) this.activeLine.removeClass('active');\n });\n }\n\n directoryClick() {\n $('a[data-action=\"directory-view\"]').on('click', function (event) {\n event.preventDefault();\n\n const path = $(this).parent().data('path') || '';\n const name = $(this).parent().data('name') || '';\n\n window.location.hash = encodeURIComponent(path + name);\n Files.list();\n });\n }\n}\n\nwindow.ContextMenu = new ContextMenuClass;\n","\"use strict\";\n\n// Copyright (c) 2015 - 2017 Dane Everitt \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\nclass FileManager {\n constructor() {\n this.list(this.decodeHash());\n }\n\n list(path, next) {\n if (_.isUndefined(path)) {\n path = this.decodeHash();\n }\n\n this.loader(true);\n $.ajax({\n type: 'POST',\n url: Pterodactyl.meta.directoryList,\n headers: {\n 'X-CSRF-Token': Pterodactyl.meta.csrftoken,\n },\n data: {\n directory: path,\n },\n }).done(data => {\n this.loader(false);\n $('#load_files').slideUp(10).html(data).slideDown(10, () => {\n ContextMenu.run();\n this.reloadFilesButton();\n this.addFolderButton();\n this.selectItem();\n this.selectAll();\n this.selectiveDeletion();\n this.selectRow();\n if (_.isFunction(next)) {\n return next();\n }\n });\n $('#internal_alert').slideUp();\n\n if (typeof Siofu === 'object') {\n Siofu.listenOnInput(document.getElementById(\"files_touch_target\"));\n }\n }).fail(jqXHR => {\n this.loader(false);\n if (_.isFunction(next)) {\n return next(new Error('Failed to load file listing.'));\n }\n\n if ((path !== '' && path !== '/') && jqXHR.status === 404) {\n return this.list('', next);\n }\n\n swal({\n type: 'error',\n title: 'File Error',\n text: jqXHR.responseJSON.errors[0].detail || 'An error occurred while attempting to process this request. Please try again.',\n });\n console.error(jqXHR);\n });\n }\n\n loader(show) {\n if (show){\n $('.file-overlay').fadeIn(100);\n } else {\n $('.file-overlay').fadeOut(100);\n }\n }\n\n reloadFilesButton() {\n $('i[data-action=\"reload-files\"]').unbind().on('click', () => {\n $('i[data-action=\"reload-files\"]').addClass('fa-spin');\n this.list();\n });\n }\n\n selectItem() {\n $('[data-action=\"addSelection\"]').on('click', event => {\n event.preventDefault();\n });\n }\n\n selectAll() {\n $('[data-action=\"selectAll\"]').on('click', event => {\n event.preventDefault();\n });\n }\n\n selectiveDeletion() {\n $('[data-action=\"selective-deletion\"]').on('mousedown', event => {\n new ActionsClass().deleteSelected();\n });\n }\n\n addFolderButton() {\n $('[data-action=\"add-folder\"]').unbind().on('click', () => {\n new ActionsClass().folder($('#file_listing').data('current-dir') || '/');\n })\n }\n\n selectRow() {\n $('#file_listing tr').on('mousedown', event => {\n if (event.which === 1) {\n if ($(event.target).is('th') || $(event.target).is('input[data-action=\"selectAll\"]')) {\n new ActionsClass().highlightAll(event);\n } else if ($(event.target).is('td') || $(event.target).is('input[data-action=\"addSelection\"]')) {\n new ActionsClass().toggleHighlight(event);\n }\n\n new ActionsClass().toggleMassActions();\n }\n });\n }\n\n decodeHash() {\n return decodeURIComponent(window.location.hash.substring(1));\n }\n\n}\n\nwindow.Files = new FileManager;\n"]} \ No newline at end of file From 4e2eafe73f13152e198f4f62e5fcd5a1587803e4 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 26 May 2018 11:42:13 -0700 Subject: [PATCH 57/66] Update dependencies --- composer.lock | 314 ++++++++++++++++++++++++++------------------------ 1 file changed, 164 insertions(+), 150 deletions(-) diff --git a/composer.lock b/composer.lock index cca82308f..ea58eb51c 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "146950cbea496a5c754d3b441ebf0118", + "content-hash": "36fe7d95a4e28ceee9aeb6e63e2187a0", "packages": [ { "name": "appstract/laravel-blade-directives", @@ -61,16 +61,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.55.11", + "version": "3.57.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "237f2acff17238ac723845e0f302d5672d0bf0a1" + "reference": "795332f5f3a81474e85653e62d1d7b306bd4eeae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/237f2acff17238ac723845e0f302d5672d0bf0a1", - "reference": "237f2acff17238ac723845e0f302d5672d0bf0a1", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/795332f5f3a81474e85653e62d1d7b306bd4eeae", + "reference": "795332f5f3a81474e85653e62d1d7b306bd4eeae", "shasum": "" }, "require": { @@ -137,7 +137,7 @@ "s3", "sdk" ], - "time": "2018-05-10T19:27:13+00:00" + "time": "2018-05-25T21:34:30+00:00" }, { "name": "cakephp/chronos", @@ -1162,16 +1162,16 @@ }, { "name": "igaster/laravel-theme", - "version": "v2.0.7", + "version": "v2.0.8", "source": { "type": "git", "url": "https://github.com/igaster/laravel-theme.git", - "reference": "b37c53021e1f523e7448a1c41e09a9d7ade11f18" + "reference": "697548f755d81175bef8c0f37c1f189a62e205bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/igaster/laravel-theme/zipball/b37c53021e1f523e7448a1c41e09a9d7ade11f18", - "reference": "b37c53021e1f523e7448a1c41e09a9d7ade11f18", + "url": "https://api.github.com/repos/igaster/laravel-theme/zipball/697548f755d81175bef8c0f37c1f189a62e205bd", + "reference": "697548f755d81175bef8c0f37c1f189a62e205bd", "shasum": "" }, "require": { @@ -1221,7 +1221,7 @@ "themes", "views" ], - "time": "2018-04-27T12:29:41+00:00" + "time": "2018-05-24T08:05:30+00:00" }, { "name": "jakub-onderka/php-console-color", @@ -1369,16 +1369,16 @@ }, { "name": "laravel/framework", - "version": "v5.6.21", + "version": "v5.6.23", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "458a89b1c5ff73072c27308566f444c790f76f28" + "reference": "f547f0a71a12763d1adb8493237d541c9e3a5d10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/458a89b1c5ff73072c27308566f444c790f76f28", - "reference": "458a89b1c5ff73072c27308566f444c790f76f28", + "url": "https://api.github.com/repos/laravel/framework/zipball/f547f0a71a12763d1adb8493237d541c9e3a5d10", + "reference": "f547f0a71a12763d1adb8493237d541c9e3a5d10", "shasum": "" }, "require": { @@ -1504,20 +1504,20 @@ "framework", "laravel" ], - "time": "2018-05-08T13:30:15+00:00" + "time": "2018-05-22T14:55:57+00:00" }, { "name": "laravel/tinker", - "version": "v1.0.6", + "version": "v1.0.7", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "b22fe905fcefdffae76b011e27c7ac09e07e052b" + "reference": "e3086ee8cb1f54a39ae8dcb72d1c37d10128997d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/b22fe905fcefdffae76b011e27c7ac09e07e052b", - "reference": "b22fe905fcefdffae76b011e27c7ac09e07e052b", + "url": "https://api.github.com/repos/laravel/tinker/zipball/e3086ee8cb1f54a39ae8dcb72d1c37d10128997d", + "reference": "e3086ee8cb1f54a39ae8dcb72d1c37d10128997d", "shasum": "" }, "require": { @@ -1567,7 +1567,7 @@ "laravel", "psysh" ], - "time": "2018-04-16T12:10:37+00:00" + "time": "2018-05-17T13:42:07+00:00" }, { "name": "league/flysystem", @@ -1890,50 +1890,6 @@ ], "time": "2017-06-19T01:22:40+00:00" }, - { - "name": "mtdowling/cron-expression", - "version": "v1.2.1", - "source": { - "type": "git", - "url": "https://github.com/mtdowling/cron-expression.git", - "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/9504fa9ea681b586028adaaa0877db4aecf32bad", - "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Cron\\": "src/Cron/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", - "keywords": [ - "cron", - "schedule" - ], - "time": "2017-01-23T04:29:33+00:00" - }, { "name": "mtdowling/jmespath.php", "version": "2.4.0", @@ -2570,16 +2526,16 @@ }, { "name": "psy/psysh", - "version": "v0.9.3", + "version": "v0.9.4", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "79c280013cf0b30fa23f3ba8bd3649218075adf4" + "reference": "4d969a0e08e1e05e7207c07cb4207017ecc9a331" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/79c280013cf0b30fa23f3ba8bd3649218075adf4", - "reference": "79c280013cf0b30fa23f3ba8bd3649218075adf4", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4d969a0e08e1e05e7207c07cb4207017ecc9a331", + "reference": "4d969a0e08e1e05e7207c07cb4207017ecc9a331", "shasum": "" }, "require": { @@ -2591,9 +2547,9 @@ "symfony/var-dumper": "~2.7|~3.0|~4.0" }, "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", "hoa/console": "~2.15|~3.16", - "phpunit/phpunit": "~4.8.35|~5.0|~6.0|~7.0", - "symfony/finder": "~2.1|~3.0|~4.0" + "phpunit/phpunit": "~4.8.35|~5.0|~6.0|~7.0" }, "suggest": { "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", @@ -2638,7 +2594,7 @@ "interactive", "shell" ], - "time": "2018-04-18T12:32:50+00:00" + "time": "2018-05-22T06:48:07+00:00" }, { "name": "ramsey/uuid", @@ -3107,16 +3063,16 @@ }, { "name": "symfony/console", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae" + "reference": "058f120b8e06ebcd7b211de5ffae07b2db00fbdd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", - "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", + "url": "https://api.github.com/repos/symfony/console/zipball/058f120b8e06ebcd7b211de5ffae07b2db00fbdd", + "reference": "058f120b8e06ebcd7b211de5ffae07b2db00fbdd", "shasum": "" }, "require": { @@ -3171,20 +3127,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-04-30T01:23:47+00:00" + "time": "2018-05-16T09:05:32+00:00" }, { "name": "symfony/css-selector", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "03f965583147957f1ecbad7ea1c9d6fd5e525ec2" + "reference": "0383a1a4eb1ffcac28719975d3e01bfa14be8ab3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/03f965583147957f1ecbad7ea1c9d6fd5e525ec2", - "reference": "03f965583147957f1ecbad7ea1c9d6fd5e525ec2", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/0383a1a4eb1ffcac28719975d3e01bfa14be8ab3", + "reference": "0383a1a4eb1ffcac28719975d3e01bfa14be8ab3", "shasum": "" }, "require": { @@ -3224,20 +3180,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2018-03-19T22:35:49+00:00" + "time": "2018-05-11T15:58:37+00:00" }, { "name": "symfony/debug", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "e1d57cdb357e5b10f5fdacbb0b86689c0a435e6e" + "reference": "4e7c98de67cc4171d4c986554e09a511da40f3d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/e1d57cdb357e5b10f5fdacbb0b86689c0a435e6e", - "reference": "e1d57cdb357e5b10f5fdacbb0b86689c0a435e6e", + "url": "https://api.github.com/repos/symfony/debug/zipball/4e7c98de67cc4171d4c986554e09a511da40f3d8", + "reference": "4e7c98de67cc4171d4c986554e09a511da40f3d8", "shasum": "" }, "require": { @@ -3280,11 +3236,11 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2018-04-30T16:59:37+00:00" + "time": "2018-05-16T09:05:32+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -3347,16 +3303,16 @@ }, { "name": "symfony/finder", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49" + "reference": "8c633f5a815903a1fe6e3fc135f207267a8a79af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", - "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", + "url": "https://api.github.com/repos/symfony/finder/zipball/8c633f5a815903a1fe6e3fc135f207267a8a79af", + "reference": "8c633f5a815903a1fe6e3fc135f207267a8a79af", "shasum": "" }, "require": { @@ -3392,20 +3348,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-04-04T05:10:37+00:00" + "time": "2018-05-16T09:05:32+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "014487772c22d893168e5d628a13e882009fea29" + "reference": "277b757a2d3960170d99d372e171a8a18916467a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/014487772c22d893168e5d628a13e882009fea29", - "reference": "014487772c22d893168e5d628a13e882009fea29", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/277b757a2d3960170d99d372e171a8a18916467a", + "reference": "277b757a2d3960170d99d372e171a8a18916467a", "shasum": "" }, "require": { @@ -3445,20 +3401,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-04-30T01:05:59+00:00" + "time": "2018-05-25T11:08:56+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "8333264b6de323ea27a08627d5396aa564fb9c25" + "reference": "450a1bda817f2dce25a9e13f0f011336743f2a48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8333264b6de323ea27a08627d5396aa564fb9c25", - "reference": "8333264b6de323ea27a08627d5396aa564fb9c25", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/450a1bda817f2dce25a9e13f0f011336743f2a48", + "reference": "450a1bda817f2dce25a9e13f0f011336743f2a48", "shasum": "" }, "require": { @@ -3466,7 +3422,8 @@ "psr/log": "~1.0", "symfony/debug": "~3.4|~4.0", "symfony/event-dispatcher": "~3.4|~4.0", - "symfony/http-foundation": "~3.4.4|~4.0.4" + "symfony/http-foundation": "~3.4.4|~4.0.4", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/config": "<3.4", @@ -3531,7 +3488,62 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2018-04-30T19:45:57+00:00" + "time": "2018-05-25T13:32:52+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-04-30T19:57:29+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -3757,16 +3769,16 @@ }, { "name": "symfony/process", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25" + "reference": "3621fa74d0576a6f89d63bc44fabd376711bd0b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25", - "reference": "d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25", + "url": "https://api.github.com/repos/symfony/process/zipball/3621fa74d0576a6f89d63bc44fabd376711bd0b0", + "reference": "3621fa74d0576a6f89d63bc44fabd376711bd0b0", "shasum": "" }, "require": { @@ -3802,20 +3814,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-04-03T05:24:00+00:00" + "time": "2018-05-16T09:05:32+00:00" }, { "name": "symfony/routing", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "1dfbfdf060bbc80da8dedc062050052e694cd027" + "reference": "e8833b64b139926cbe1610d53722185e55c18e44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/1dfbfdf060bbc80da8dedc062050052e694cd027", - "reference": "1dfbfdf060bbc80da8dedc062050052e694cd027", + "url": "https://api.github.com/repos/symfony/routing/zipball/e8833b64b139926cbe1610d53722185e55c18e44", + "reference": "e8833b64b139926cbe1610d53722185e55c18e44", "shasum": "" }, "require": { @@ -3880,20 +3892,20 @@ "uri", "url" ], - "time": "2018-04-20T06:20:23+00:00" + "time": "2018-05-16T14:21:07+00:00" }, { "name": "symfony/translation", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "ad3abf08eb3450491d8d76513100ef58194cd13e" + "reference": "e1f5863d0a9e79cfec7f031421ced3fe1d403e66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/ad3abf08eb3450491d8d76513100ef58194cd13e", - "reference": "ad3abf08eb3450491d8d76513100ef58194cd13e", + "url": "https://api.github.com/repos/symfony/translation/zipball/e1f5863d0a9e79cfec7f031421ced3fe1d403e66", + "reference": "e1f5863d0a9e79cfec7f031421ced3fe1d403e66", "shasum": "" }, "require": { @@ -3948,11 +3960,11 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2018-04-30T01:23:47+00:00" + "time": "2018-05-21T10:09:47+00:00" }, { "name": "symfony/var-dumper", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", @@ -4222,16 +4234,16 @@ "packages-dev": [ { "name": "barryvdh/laravel-debugbar", - "version": "v3.1.4", + "version": "v3.1.5", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-debugbar.git", - "reference": "7a91480cc6e597caed5117a3c5d685f06d35c5a1" + "reference": "d3cdca2ad6cc6e67735b4a63e7551c690a497f5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/7a91480cc6e597caed5117a3c5d685f06d35c5a1", - "reference": "7a91480cc6e597caed5117a3c5d685f06d35c5a1", + "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/d3cdca2ad6cc6e67735b4a63e7551c690a497f5f", + "reference": "d3cdca2ad6cc6e67735b4a63e7551c690a497f5f", "shasum": "" }, "require": { @@ -4286,7 +4298,7 @@ "profiler", "webprofiler" ], - "time": "2018-03-06T08:35:31+00:00" + "time": "2018-05-03T18:27:04+00:00" }, { "name": "barryvdh/laravel-ide-helper", @@ -4412,16 +4424,16 @@ }, { "name": "codedungeon/php-cli-colors", - "version": "1.10.3", + "version": "1.10.7", "source": { "type": "git", "url": "https://github.com/mikeerickson/php-cli-colors.git", - "reference": "1beb5c21b21b2c125aff26a75caf02fcec12571f" + "reference": "5649ef76ec0c9ed626e95bf40fdfaf4b8efcf79b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mikeerickson/php-cli-colors/zipball/1beb5c21b21b2c125aff26a75caf02fcec12571f", - "reference": "1beb5c21b21b2c125aff26a75caf02fcec12571f", + "url": "https://api.github.com/repos/mikeerickson/php-cli-colors/zipball/5649ef76ec0c9ed626e95bf40fdfaf4b8efcf79b", + "reference": "5649ef76ec0c9ed626e95bf40fdfaf4b8efcf79b", "shasum": "" }, "require-dev": { @@ -4452,7 +4464,7 @@ "package", "php" ], - "time": "2017-09-12T17:12:52+00:00" + "time": "2018-05-17T01:34:14+00:00" }, { "name": "codedungeon/phpunit-result-printer", @@ -6652,7 +6664,7 @@ }, { "name": "symfony/class-loader", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", @@ -6708,20 +6720,21 @@ }, { "name": "symfony/filesystem", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21" + "reference": "7a69e728e9f0044958c2fd7d72bfe5e7bd1a4d04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", - "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/7a69e728e9f0044958c2fd7d72bfe5e7bd1a4d04", + "reference": "7a69e728e9f0044958c2fd7d72bfe5e7bd1a4d04", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" }, "type": "library", "extra": { @@ -6753,20 +6766,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-02-22T10:50:29+00:00" + "time": "2018-05-16T09:05:32+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0" + "reference": "ac1c3a814ddcad9d0cc2d0382e215d3bff8ae2d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/371532a2cfe932f7a3766dd4c45364566def1dd0", - "reference": "371532a2cfe932f7a3766dd4c45364566def1dd0", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/ac1c3a814ddcad9d0cc2d0382e215d3bff8ae2d2", + "reference": "ac1c3a814ddcad9d0cc2d0382e215d3bff8ae2d2", "shasum": "" }, "require": { @@ -6807,7 +6820,7 @@ "configuration", "options" ], - "time": "2018-01-18T22:19:33+00:00" + "time": "2018-05-11T15:58:37+00:00" }, { "name": "symfony/polyfill-php70", @@ -6870,7 +6883,7 @@ }, { "name": "symfony/stopwatch", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -6919,20 +6932,21 @@ }, { "name": "symfony/yaml", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "275ad099e4cbe612a2acbca14a16dd1c5311324d" + "reference": "048b1be5fb96e73ff1d065f5e7e23f84415ac907" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/275ad099e4cbe612a2acbca14a16dd1c5311324d", - "reference": "275ad099e4cbe612a2acbca14a16dd1c5311324d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/048b1be5fb96e73ff1d065f5e7e23f84415ac907", + "reference": "048b1be5fb96e73ff1d065f5e7e23f84415ac907", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/console": "<3.4" @@ -6973,7 +6987,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-04-08T08:49:08+00:00" + "time": "2018-05-07T07:12:24+00:00" }, { "name": "theseer/tokenizer", From 86e70853960f89dd308aa475834deabcff44f661 Mon Sep 17 00:00:00 2001 From: stanjg Date: Sat, 26 May 2018 20:58:49 +0200 Subject: [PATCH 58/66] Cleaned up the controller and prepared for tests --- .../Repository/RepositoryInterface.php | 7 ++ .../Admin/StatisticsController.php | 65 +++++++++++++------ .../Eloquent/EloquentRepository.php | 10 +++ .../JavascriptStatisticsInjection.php | 24 +++++++ 4 files changed, 85 insertions(+), 21 deletions(-) create mode 100644 app/Traits/Controllers/JavascriptStatisticsInjection.php diff --git a/app/Contracts/Repository/RepositoryInterface.php b/app/Contracts/Repository/RepositoryInterface.php index 4a098c34f..3da9da009 100644 --- a/app/Contracts/Repository/RepositoryInterface.php +++ b/app/Contracts/Repository/RepositoryInterface.php @@ -200,4 +200,11 @@ interface RepositoryInterface * @return bool */ public function insertIgnore(array $values): bool; + + /** + * Get the amount of entries in the database + * + * @return int + */ + public function count(): int; } diff --git a/app/Http/Controllers/Admin/StatisticsController.php b/app/Http/Controllers/Admin/StatisticsController.php index aedca3d6b..984b6de22 100644 --- a/app/Http/Controllers/Admin/StatisticsController.php +++ b/app/Http/Controllers/Admin/StatisticsController.php @@ -5,52 +5,75 @@ namespace Pterodactyl\Http\Controllers\Admin; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use JavaScript; +use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; +use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface; +use Pterodactyl\Contracts\Repository\EggRepositoryInterface; +use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; +use Pterodactyl\Contracts\Repository\ServerRepositoryInterface; +use Pterodactyl\Contracts\Repository\UserRepositoryInterface; use Pterodactyl\Http\Controllers\Controller; -use Pterodactyl\Models\Allocation; -use Pterodactyl\Models\Database; -use Pterodactyl\Models\Egg; -use Pterodactyl\Models\Node; -use Pterodactyl\Models\Server; -use Pterodactyl\Models\User; use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; +use Pterodactyl\Traits\Controllers\JavascriptInjection; class StatisticsController extends Controller { + use JavascriptInjection; + + private $allocationRepository; + + private $databaseRepository; private $keyProviderService; - function __construct(DaemonKeyProviderService $keyProviderService) + private $eggRepository; + + private $nodeRepository; + + private $serverRepository; + + private $userRepository; + + function __construct( + AllocationRepositoryInterface $allocationRepository, + DatabaseRepositoryInterface $databaseRepository, + DaemonKeyProviderService $keyProviderService, + EggRepositoryInterface $eggRepository, + NodeRepositoryInterface $nodeRepository, + ServerRepositoryInterface $serverRepository, + UserRepositoryInterface $userRepository + ) { + $this->allocationRepository = $allocationRepository; + $this->databaseRepository = $databaseRepository; $this->keyProviderService = $keyProviderService; + $this->eggRepository = $eggRepository; + $this->nodeRepository = $nodeRepository; + $this->serverRepository = $serverRepository; + $this->userRepository = $userRepository; } public function index(Request $request) { - $servers = Server::all(); - $nodes = Node::all(); + $servers = $this->serverRepository->all(); $serversCount = count($servers); + $nodes = $this->nodeRepository->all(); $nodesCount = count($nodes); - $usersCount = User::count(); - $eggsCount = Egg::count(); - $databasesCount = Database::count(); + $usersCount = $this->userRepository->count(); + $eggsCount = $this->eggRepository->count(); + $databasesCount = $this->databaseRepository->count(); $totalServerRam = DB::table('servers')->sum('memory'); $totalNodeRam = DB::table('nodes')->sum('memory'); $totalServerDisk = DB::table('servers')->sum('disk'); $totalNodeDisk = DB::table('nodes')->sum('disk'); - $totalAllocations = Allocation::count(); - - $suspendedServersCount = Server::where('suspended', true)->count(); + $totalAllocations = $this->allocationRepository->count(); + $suspendedServersCount = $this->serverRepository->getBuilder()->where('suspended', true)->count(); $tokens = []; foreach ($nodes as $node) { - $server = Server::where('node_id', $node->id)->first(); - if ($server == null) - continue; - - $tokens[$node->id] = $this->keyProviderService->handle($server, $request->user()); + $tokens[$node->id] = $node->daemonSecret; } - Javascript::put([ + $this->injectJavascript([ 'servers' => $servers, 'serverCount' => $serversCount, 'suspendedServers' => $suspendedServersCount, diff --git a/app/Repositories/Eloquent/EloquentRepository.php b/app/Repositories/Eloquent/EloquentRepository.php index 74ec809fe..64e7cfb60 100644 --- a/app/Repositories/Eloquent/EloquentRepository.php +++ b/app/Repositories/Eloquent/EloquentRepository.php @@ -296,4 +296,14 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf return $this->getBuilder()->getConnection()->statement($statement, $bindings); } + + /** + * Get the amount of entries in the database + * + * @return int + */ + public function count(): int + { + return $this->getBuilder()->count(); + } } diff --git a/app/Traits/Controllers/JavascriptStatisticsInjection.php b/app/Traits/Controllers/JavascriptStatisticsInjection.php new file mode 100644 index 000000000..779764233 --- /dev/null +++ b/app/Traits/Controllers/JavascriptStatisticsInjection.php @@ -0,0 +1,24 @@ + Date: Sat, 26 May 2018 21:02:47 +0200 Subject: [PATCH 59/66] Wording changes and fix of major fail last commit --- app/Http/Controllers/Admin/StatisticsController.php | 5 ++--- app/Traits/Controllers/JavascriptStatisticsInjection.php | 2 +- public/themes/pterodactyl/js/admin/statistics.js | 4 ++-- resources/themes/pterodactyl/admin/statistics.blade.php | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Admin/StatisticsController.php b/app/Http/Controllers/Admin/StatisticsController.php index 984b6de22..07124e4b6 100644 --- a/app/Http/Controllers/Admin/StatisticsController.php +++ b/app/Http/Controllers/Admin/StatisticsController.php @@ -4,7 +4,6 @@ namespace Pterodactyl\Http\Controllers\Admin; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; -use JavaScript; use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface; use Pterodactyl\Contracts\Repository\EggRepositoryInterface; @@ -13,11 +12,11 @@ use Pterodactyl\Contracts\Repository\ServerRepositoryInterface; use Pterodactyl\Contracts\Repository\UserRepositoryInterface; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; -use Pterodactyl\Traits\Controllers\JavascriptInjection; +use Pterodactyl\Traits\Controllers\JavascriptStatisticsInjection; class StatisticsController extends Controller { - use JavascriptInjection; + use JavascriptStatisticsInjection; private $allocationRepository; diff --git a/app/Traits/Controllers/JavascriptStatisticsInjection.php b/app/Traits/Controllers/JavascriptStatisticsInjection.php index 779764233..3b4e52d0f 100644 --- a/app/Traits/Controllers/JavascriptStatisticsInjection.php +++ b/app/Traits/Controllers/JavascriptStatisticsInjection.php @@ -10,7 +10,7 @@ namespace Pterodactyl\Traits\Controllers; use JavaScript; -class JavascriptStatisticsInjection +trait JavascriptStatisticsInjection { /** diff --git a/public/themes/pterodactyl/js/admin/statistics.js b/public/themes/pterodactyl/js/admin/statistics.js index 12f4277bd..59034a8da 100644 --- a/public/themes/pterodactyl/js/admin/statistics.js +++ b/public/themes/pterodactyl/js/admin/statistics.js @@ -5,7 +5,7 @@ let diskChart = new Chart($('#disk_chart'), { labels: ['Free Disk', 'Used Disk'], datasets: [ { - label: 'Disk in MBs', + label: 'Disk (in MB)', backgroundColor: ['#51B060', '#ff0000'], data: [freeDisk, Pterodactyl.totalServerDisk] } @@ -20,7 +20,7 @@ let ramChart = new Chart($('#ram_chart'), { labels: ['Free RAM', 'Used RAM'], datasets: [ { - label: 'RAM in MBs', + label: 'Memory (in MB)', backgroundColor: ['#51B060', '#ff0000'], data: [freeRam, Pterodactyl.totalServerRam] } diff --git a/resources/themes/pterodactyl/admin/statistics.blade.php b/resources/themes/pterodactyl/admin/statistics.blade.php index 46e112336..036ad937f 100644 --- a/resources/themes/pterodactyl/admin/statistics.blade.php +++ b/resources/themes/pterodactyl/admin/statistics.blade.php @@ -41,14 +41,14 @@
    - Total used RAM + Total used Memory (in MB) {{ $totalServerRam }}MB
    - Total used disk space + Total used Disk (in MB) {{ $totalServerDisk }}MB
    From 60e1ffa56497e5fe9bee8da8a06e74e54b328e60 Mon Sep 17 00:00:00 2001 From: stanjg Date: Sun, 27 May 2018 00:16:13 +0200 Subject: [PATCH 60/66] Added a test for the controller and cleaned up the controller --- .../Repository/NodeRepositoryInterface.php | 8 ++ .../Repository/ServerRepositoryInterface.php | 7 ++ .../Admin/StatisticsController.php | 38 +++--- app/Repositories/Eloquent/NodeRepository.php | 27 +++++ .../Eloquent/ServerRepository.php | 10 ++ ...ction.php => PlainJavascriptInjection.php} | 2 +- .../themes/pterodactyl/js/admin/statistics.js | 2 +- .../pterodactyl/admin/statistics.blade.php | 4 +- .../Admin/StatisticsControllerTest.php | 113 ++++++++++++++++++ 9 files changed, 188 insertions(+), 23 deletions(-) rename app/Traits/Controllers/{JavascriptStatisticsInjection.php => PlainJavascriptInjection.php} (89%) create mode 100644 tests/Unit/Http/Controllers/Admin/StatisticsControllerTest.php diff --git a/app/Contracts/Repository/NodeRepositoryInterface.php b/app/Contracts/Repository/NodeRepositoryInterface.php index 0ebcbe3a0..c533032c0 100644 --- a/app/Contracts/Repository/NodeRepositoryInterface.php +++ b/app/Contracts/Repository/NodeRepositoryInterface.php @@ -21,6 +21,14 @@ interface NodeRepositoryInterface extends RepositoryInterface, SearchableInterfa */ public function getUsageStats(Node $node): array; + /** + * Return the usage stats for a single node. + * + * @param \Pterodactyl\Models\Node $node + * @return array + */ + public function getUsageStatsRaw(Node $node): array; + /** * Return all available nodes with a searchable interface. * diff --git a/app/Contracts/Repository/ServerRepositoryInterface.php b/app/Contracts/Repository/ServerRepositoryInterface.php index dc677fba0..9fb712e29 100644 --- a/app/Contracts/Repository/ServerRepositoryInterface.php +++ b/app/Contracts/Repository/ServerRepositoryInterface.php @@ -145,4 +145,11 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter * @return bool */ public function isUniqueUuidCombo(string $uuid, string $short): bool; + + /** + * Get the amount of servers that are suspended + * + * @return int + */ + public function getSuspendedServersCount(): int; } diff --git a/app/Http/Controllers/Admin/StatisticsController.php b/app/Http/Controllers/Admin/StatisticsController.php index 07124e4b6..2327fd88d 100644 --- a/app/Http/Controllers/Admin/StatisticsController.php +++ b/app/Http/Controllers/Admin/StatisticsController.php @@ -11,19 +11,16 @@ use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; use Pterodactyl\Contracts\Repository\ServerRepositoryInterface; use Pterodactyl\Contracts\Repository\UserRepositoryInterface; use Pterodactyl\Http\Controllers\Controller; -use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; -use Pterodactyl\Traits\Controllers\JavascriptStatisticsInjection; +use Pterodactyl\Traits\Controllers\PlainJavascriptInjection; class StatisticsController extends Controller { - use JavascriptStatisticsInjection; + use PlainJavascriptInjection; private $allocationRepository; private $databaseRepository; - private $keyProviderService; - private $eggRepository; private $nodeRepository; @@ -35,7 +32,6 @@ class StatisticsController extends Controller function __construct( AllocationRepositoryInterface $allocationRepository, DatabaseRepositoryInterface $databaseRepository, - DaemonKeyProviderService $keyProviderService, EggRepositoryInterface $eggRepository, NodeRepositoryInterface $nodeRepository, ServerRepositoryInterface $serverRepository, @@ -44,28 +40,33 @@ class StatisticsController extends Controller { $this->allocationRepository = $allocationRepository; $this->databaseRepository = $databaseRepository; - $this->keyProviderService = $keyProviderService; $this->eggRepository = $eggRepository; $this->nodeRepository = $nodeRepository; $this->serverRepository = $serverRepository; $this->userRepository = $userRepository; } - public function index(Request $request) + public function index() { $servers = $this->serverRepository->all(); - $serversCount = count($servers); $nodes = $this->nodeRepository->all(); - $nodesCount = count($nodes); $usersCount = $this->userRepository->count(); $eggsCount = $this->eggRepository->count(); $databasesCount = $this->databaseRepository->count(); - $totalServerRam = DB::table('servers')->sum('memory'); - $totalNodeRam = DB::table('nodes')->sum('memory'); - $totalServerDisk = DB::table('servers')->sum('disk'); - $totalNodeDisk = DB::table('nodes')->sum('disk'); $totalAllocations = $this->allocationRepository->count(); - $suspendedServersCount = $this->serverRepository->getBuilder()->where('suspended', true)->count(); + $suspendedServersCount = $this->serverRepository->getSuspendedServersCount(); + + $totalServerRam = 0; + $totalNodeRam = 0; + $totalServerDisk = 0; + $totalNodeDisk = 0; + foreach ($nodes as $node) { + $stats = $this->nodeRepository->getUsageStatsRaw($node); + $totalServerRam += $stats['memory']['value']; + $totalNodeRam += $stats['memory']['max']; + $totalServerDisk += $stats['disk']['value']; + $totalNodeDisk += $stats['disk']['max']; + } $tokens = []; foreach ($nodes as $node) { @@ -74,7 +75,6 @@ class StatisticsController extends Controller $this->injectJavascript([ 'servers' => $servers, - 'serverCount' => $serversCount, 'suspendedServers' => $suspendedServersCount, 'totalServerRam' => $totalServerRam, 'totalNodeRam' => $totalNodeRam, @@ -83,10 +83,10 @@ class StatisticsController extends Controller 'nodes' => $nodes, 'tokens' => $tokens, ]); - + return view('admin.statistics', [ - 'serversCount' => $serversCount, - 'nodesCount' => $nodesCount, + 'servers' => $servers, + 'nodes' => $nodes, 'usersCount' => $usersCount, 'eggsCount' => $eggsCount, 'totalServerRam' => $totalServerRam, diff --git a/app/Repositories/Eloquent/NodeRepository.php b/app/Repositories/Eloquent/NodeRepository.php index b4d6ba6b0..4f59fddce 100644 --- a/app/Repositories/Eloquent/NodeRepository.php +++ b/app/Repositories/Eloquent/NodeRepository.php @@ -56,6 +56,33 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa })->toArray(); } + /** + * Return the usage stats for a single node. + * + * @param \Pterodactyl\Models\Node $node + * @return array + */ + public function getUsageStatsRaw(Node $node): array + { + $stats = $this->getBuilder()->select( + $this->getBuilder()->raw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk') + )->join('servers', 'servers.node_id', '=', 'nodes.id')->where('node_id', $node->id)->first(); + + return collect(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory])->mapWithKeys(function ($value, $key) use ($node) { + $maxUsage = $node->{$key}; + if ($node->{$key . '_overallocate'} > 0) { + $maxUsage = $node->{$key} * (1 + ($node->{$key . '_overallocate'} / 100)); + } + + return [ + $key => [ + 'value' => $value, + 'max' => $maxUsage, + ], + ]; + })->toArray(); + } + /** * Return all available nodes with a searchable interface. * diff --git a/app/Repositories/Eloquent/ServerRepository.php b/app/Repositories/Eloquent/ServerRepository.php index 2fc5f878b..c2c6e1e32 100644 --- a/app/Repositories/Eloquent/ServerRepository.php +++ b/app/Repositories/Eloquent/ServerRepository.php @@ -328,4 +328,14 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt $this->app->make(SubuserRepository::class)->getBuilder()->select('server_id')->where('user_id', $user) )->pluck('id')->all(); } + + /** + * Get the amount of servers that are suspended + * + * @return int + */ + public function getSuspendedServersCount(): int + { + return $this->getBuilder()->where('suspended', true)->count(); + } } diff --git a/app/Traits/Controllers/JavascriptStatisticsInjection.php b/app/Traits/Controllers/PlainJavascriptInjection.php similarity index 89% rename from app/Traits/Controllers/JavascriptStatisticsInjection.php rename to app/Traits/Controllers/PlainJavascriptInjection.php index 3b4e52d0f..eae53bfbc 100644 --- a/app/Traits/Controllers/JavascriptStatisticsInjection.php +++ b/app/Traits/Controllers/PlainJavascriptInjection.php @@ -10,7 +10,7 @@ namespace Pterodactyl\Traits\Controllers; use JavaScript; -trait JavascriptStatisticsInjection +trait PlainJavascriptInjection { /** diff --git a/public/themes/pterodactyl/js/admin/statistics.js b/public/themes/pterodactyl/js/admin/statistics.js index 59034a8da..7433f3221 100644 --- a/public/themes/pterodactyl/js/admin/statistics.js +++ b/public/themes/pterodactyl/js/admin/statistics.js @@ -28,7 +28,7 @@ let ramChart = new Chart($('#ram_chart'), { } }); -var activeServers = Pterodactyl.serverCount - Pterodactyl.suspendedServers; +var activeServers = Pterodactyl.servers.length - Pterodactyl.suspendedServers; let serversChart = new Chart($('#servers_chart'), { type: 'pie', data: { diff --git a/resources/themes/pterodactyl/admin/statistics.blade.php b/resources/themes/pterodactyl/admin/statistics.blade.php index 036ad937f..529107bb4 100644 --- a/resources/themes/pterodactyl/admin/statistics.blade.php +++ b/resources/themes/pterodactyl/admin/statistics.blade.php @@ -35,7 +35,7 @@
    Servers - {{ $serversCount }} + {{ count($servers) }}
    @@ -118,7 +118,7 @@
    Total Nodes - {{ $nodesCount }} + {{ count($nodes) }}
    diff --git a/tests/Unit/Http/Controllers/Admin/StatisticsControllerTest.php b/tests/Unit/Http/Controllers/Admin/StatisticsControllerTest.php new file mode 100644 index 000000000..f3a20f8ac --- /dev/null +++ b/tests/Unit/Http/Controllers/Admin/StatisticsControllerTest.php @@ -0,0 +1,113 @@ +allocationRepository = m::mock(AllocationRepositoryInterface::class); + $this->databaseRepository = m::mock(DatabaseRepositoryInterface::class); + $this->eggRepository = m::mock(EggRepositoryInterface::class); + $this->nodeRepository = m::mock(NodeRepositoryInterface::class); + $this->serverRepository = m::mock(ServerRepositoryInterface::class); + $this->userRepository = m::mock(UserRepositoryInterface::class); + } + + public function testIndexController() + { + $controller = $this->getController(); + + $this->serverRepository->shouldReceive('all')->withNoArgs(); + $this->nodeRepository->shouldReceive('all')->withNoArgs()->andReturn(collect([factory(Node::class)->make(), factory(Node::class)->make()])); + $this->userRepository->shouldReceive('count')->withNoArgs(); + $this->eggRepository->shouldReceive('count')->withNoArgs(); + $this->databaseRepository->shouldReceive('count')->withNoArgs(); + $this->allocationRepository->shouldReceive('count')->withNoArgs(); + $this->serverRepository->shouldReceive('getSuspendedServersCount')->withNoArgs(); + + $this->nodeRepository->shouldReceive('getUsageStatsRaw')->twice()->andReturn([ + 'memory' => [ + 'value' => 1024, + 'max' => 512, + ], + 'disk' => [ + 'value' => 1024, + 'max' => 512, + ] + ]); + + $controller->shouldReceive('injectJavascript')->once(); + + $response = $controller->index(); + + $this->assertIsViewResponse($response); + $this->assertViewNameEquals('admin.statistics', $response); + } + + private function getController() + { + return $this->buildMockedController(StatisticsController::class, [$this->allocationRepository, + $this->databaseRepository, + $this->eggRepository, + $this->nodeRepository, + $this->serverRepository, + $this->userRepository] + ); + } + +} \ No newline at end of file From 013dde75ae237422cddc8abbe9183b8274b6e44a Mon Sep 17 00:00:00 2001 From: stanjg Date: Thu, 31 May 2018 16:34:35 +0200 Subject: [PATCH 61/66] Renamed the field and made some improvements --- app/Http/Middleware/MaintenanceMiddleware.php | 2 +- app/Models/Node.php | 8 ++++---- .../2018_05_04_123826_add_maintenance_to_nodes.php | 4 ++-- resources/lang/en/strings.php | 1 + .../themes/pterodactyl/admin/nodes/index.blade.php | 2 +- .../pterodactyl/admin/nodes/view/index.blade.php | 2 +- .../pterodactyl/admin/nodes/view/settings.blade.php | 10 +++++----- resources/themes/pterodactyl/base/index.blade.php | 4 ++-- 8 files changed, 17 insertions(+), 16 deletions(-) diff --git a/app/Http/Middleware/MaintenanceMiddleware.php b/app/Http/Middleware/MaintenanceMiddleware.php index 39f260594..c67a3f051 100644 --- a/app/Http/Middleware/MaintenanceMiddleware.php +++ b/app/Http/Middleware/MaintenanceMiddleware.php @@ -35,7 +35,7 @@ class MaintenanceMiddleware $server = $request->attributes->get('server'); $node = $server->getRelation('node'); - if ($node->maintenance) { + if ($node->maintenance_mode) { return $this->response->view('errors.maintenance'); } diff --git a/app/Models/Node.php b/app/Models/Node.php index ea0258e8f..2643d062a 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -48,7 +48,7 @@ class Node extends Model implements CleansAttributes, ValidableContract 'daemonSFTP' => 'integer', 'behind_proxy' => 'boolean', 'public' => 'boolean', - 'maintenance' => 'boolean', + 'maintenance_mode' => 'boolean', ]; /** @@ -63,7 +63,7 @@ class Node extends Model implements CleansAttributes, ValidableContract 'disk_overallocate', 'upload_size', 'daemonSecret', 'daemonBase', 'daemonSFTP', 'daemonListen', - 'description', 'maintenance', + 'description', 'maintenance_mode', ]; /** @@ -112,7 +112,7 @@ class Node extends Model implements CleansAttributes, ValidableContract 'daemonBase' => 'regex:/^([\/][\d\w.\-\/]+)$/', 'daemonSFTP' => 'numeric|between:1024,65535', 'daemonListen' => 'numeric|between:1024,65535', - 'maintenance' => 'boolean', + 'maintenance_mode' => 'boolean', ]; /** @@ -128,7 +128,7 @@ class Node extends Model implements CleansAttributes, ValidableContract 'daemonBase' => '/srv/daemon-data', 'daemonSFTP' => 2022, 'daemonListen' => 8080, - 'maintenance' => false, + 'maintenance_mode' => false, ]; /** diff --git a/database/migrations/2018_05_04_123826_add_maintenance_to_nodes.php b/database/migrations/2018_05_04_123826_add_maintenance_to_nodes.php index 6c55912aa..799f1df23 100644 --- a/database/migrations/2018_05_04_123826_add_maintenance_to_nodes.php +++ b/database/migrations/2018_05_04_123826_add_maintenance_to_nodes.php @@ -14,7 +14,7 @@ class AddMaintenanceToNodes extends Migration public function up() { Schema::table('nodes', function (Blueprint $table) { - $table->boolean('maintenance')->after('behind_proxy')->default(false); + $table->boolean('maintenance_mode')->after('behind_proxy')->default(false); }); } @@ -26,7 +26,7 @@ class AddMaintenanceToNodes extends Migration public function down() { Schema::table('nodes', function (Blueprint $table) { - $table->dropColumn('maintenance'); + $table->dropColumn('maintenance_mode'); }); } } diff --git a/resources/lang/en/strings.php b/resources/lang/en/strings.php index 5b9173866..c0bf3f417 100644 --- a/resources/lang/en/strings.php +++ b/resources/lang/en/strings.php @@ -74,6 +74,7 @@ return [ 'tasks' => 'Tasks', 'seconds' => 'Seconds', 'minutes' => 'Minutes', + 'under_maintenance' => 'Under Maintenance', 'days' => [ 'sun' => 'Sunday', 'mon' => 'Monday', diff --git a/resources/themes/pterodactyl/admin/nodes/index.blade.php b/resources/themes/pterodactyl/admin/nodes/index.blade.php index abaf25e54..b4ea579a1 100644 --- a/resources/themes/pterodactyl/admin/nodes/index.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/index.blade.php @@ -56,7 +56,7 @@ @foreach ($nodes as $node) - {{ $node->name }} + {!! $node->maintenance_mode ? ' ' : '' !!}{{ $node->name }} {{ $node->location->short }} {{ $node->memory }} MB {{ $node->disk }} MB diff --git a/resources/themes/pterodactyl/admin/nodes/view/index.blade.php b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php index 5ee0a88f2..71eb346d2 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/index.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php @@ -96,7 +96,7 @@
    - @if($node->maintenance) + @if($node->maintenance_mode)
    diff --git a/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php b/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php index 0e042fab4..5afd65ed4 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php @@ -109,15 +109,15 @@

    If you are running the daemon behind a proxy such as Cloudflare, select this to have the daemon skip looking for certificates on boot.

    - +
    - maintenance) == false) ? 'checked' : '' }}> - + maintenance_mode) == false) ? 'checked' : '' }}> +
    - maintenance) == true) ? 'checked' : '' }}> - + maintenance_mode) == true) ? 'checked' : '' }}> +

    If the node is marked as 'Under Maintenance' users won't be able to access servers that are on this node.

    diff --git a/resources/themes/pterodactyl/base/index.blade.php b/resources/themes/pterodactyl/base/index.blade.php index 09596298c..28f4c4d57 100644 --- a/resources/themes/pterodactyl/base/index.blade.php +++ b/resources/themes/pterodactyl/base/index.blade.php @@ -64,9 +64,9 @@ @lang('strings.subuser') @endif - @if($server->node->maintenance) + @if($server->node->maintenance_mode) - Maintenance + @lang('strings.under_maintenance') @else From ccf3e3511f6344239dcc49ed7dbcb667c7f0461a Mon Sep 17 00:00:00 2001 From: stanjg Date: Thu, 31 May 2018 16:40:18 +0200 Subject: [PATCH 62/66] Renamed middleware, and fixed the test --- app/Http/Kernel.php | 2 +- app/Providers/RouteServiceProvider.php | 2 +- tests/Unit/Http/Middleware/MaintenanceMiddlewareTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 4221672e9..d21c8d3c8 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -109,7 +109,7 @@ class Kernel extends HttpKernel 'can' => Authorize::class, 'bindings' => SubstituteBindings::class, 'recaptcha' => VerifyReCaptcha::class, - 'maintenance' => MaintenanceMiddleware::class, + 'node.maintenance' => MaintenanceMiddleware::class, // Server specific middleware (used for authenticating access to resources) // diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 3604b3d79..f0e978116 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -33,7 +33,7 @@ class RouteServiceProvider extends ServiceProvider ->namespace($this->namespace . '\Auth') ->group(base_path('routes/auth.php')); - Route::middleware(['web', 'csrf', 'auth', 'server', 'subuser.auth', 'maintenance'])->prefix('/server/{server}') + Route::middleware(['web', 'csrf', 'auth', 'server', 'subuser.auth', 'node.maintenance'])->prefix('/server/{server}') ->namespace($this->namespace . '\Server') ->group(base_path('routes/server.php')); diff --git a/tests/Unit/Http/Middleware/MaintenanceMiddlewareTest.php b/tests/Unit/Http/Middleware/MaintenanceMiddlewareTest.php index 6b7380f3b..fedeaa0c6 100644 --- a/tests/Unit/Http/Middleware/MaintenanceMiddlewareTest.php +++ b/tests/Unit/Http/Middleware/MaintenanceMiddlewareTest.php @@ -46,7 +46,7 @@ class MaintenanceMiddlewareTest extends MiddlewareTestCase public function testHandleInMaintenanceMode() { $server = factory(Server::class)->make(); - $node = factory(Node::class)->make(['maintenance' => 1]); + $node = factory(Node::class)->make(['maintenance_mode' => 1]); $server->setRelation('node', $node); $this->setRequestAttribute('server', $server); From 6e6ce652b24d23a0050e500e326a1141a78e761e Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Thu, 31 May 2018 21:35:24 -0600 Subject: [PATCH 63/66] Fix logo-mini image (#1183) --- resources/themes/pterodactyl/layouts/master.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/pterodactyl/layouts/master.blade.php b/resources/themes/pterodactyl/layouts/master.blade.php index c46db68b8..644cb5bca 100644 --- a/resources/themes/pterodactyl/layouts/master.blade.php +++ b/resources/themes/pterodactyl/layouts/master.blade.php @@ -44,7 +44,7 @@