From b926d432e8011fd540e02f398037dda4420dea4a Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 18 Feb 2017 19:31:44 -0500 Subject: [PATCH 01/35] Thats enough re-theming for the day... --- .../Controllers/Admin/ServersController.php | 53 ++-- app/Http/Controllers/Admin/UserController.php | 8 +- app/Http/Middleware/AdminAuthenticate.php | 3 - app/Http/Routes/AdminRoutes.php | 4 + app/Models/Server.php | 19 +- app/Models/User.php | 13 +- composer.json | 3 +- composer.lock | 50 +++- public/js/laroute.js | 2 +- public/themes/pterodactyl/css/pterodactyl.css | 17 ++ .../themes/pterodactyl/admin/index.blade.php | 71 ++++++ .../pterodactyl/admin/servers/index.blade.php | 94 +++++++ .../pterodactyl/admin/servers/new.blade.php | 230 ++++++++++++++++++ .../pterodactyl/layouts/admin.blade.php | 198 +++++++++++++++ .../pterodactyl/layouts/master.blade.php | 6 +- 15 files changed, 733 insertions(+), 38 deletions(-) create mode 100644 resources/themes/pterodactyl/admin/index.blade.php create mode 100644 resources/themes/pterodactyl/admin/servers/index.blade.php create mode 100644 resources/themes/pterodactyl/admin/servers/new.blade.php create mode 100644 resources/themes/pterodactyl/layouts/admin.blade.php diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 0f5cf495d..daacc9f08 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -46,8 +46,16 @@ class ServersController extends Controller public function getIndex(Request $request) { + $servers = Models\Server::withTrashed()->with( + 'node', 'user', 'allocation' + ); + + if (! is_null($request->input('query'))) { + $servers->search($request->input('query')); + } + return view('admin.servers.index', [ - 'servers' => Models\Server::withTrashed()->with('node', 'user')->paginate(25), + 'servers' => $servers->paginate(25), ]); } @@ -109,13 +117,25 @@ class ServersController extends Controller */ public function postNewServerGetNodes(Request $request) { - if (! $request->input('location')) { - return response()->json([ - 'error' => 'Missing location in request.', - ], 500); - } + $nodes = Models\Node::with('allocations')->where('location_id', $request->input('location'))->get(); + return $nodes->map(function ($item) { + $filtered = $item->allocations->map(function($map) { + return collect($map)->only(['ip', 'port']); + }); - return response()->json(Models\Node::select('id', 'name', 'public')->where('location_id', $request->input('location'))->get()); + $item->ports = $filtered->unique('ip')->map(function ($map) use ($item) { + return [ + 'ip' => $map['ip'], + 'ports' => $item->allocations->where('ip', $map['ip'])->pluck('port')->all(), + ]; + })->values(); + + return [ + 'id' => $item->id, + 'text' => $item->name, + 'allocations' => $item->ports, + ]; + })->values(); } /** @@ -126,24 +146,7 @@ class ServersController extends Controller */ public function postNewServerGetIps(Request $request) { - if (! $request->input('node')) { - return response()->json([ - 'error' => 'Missing node in request.', - ], 500); - } - - $ips = Models\Allocation::where('node_id', $request->input('node'))->whereNull('server_id')->get(); - $listing = []; - - foreach ($ips as &$ip) { - if (array_key_exists($ip->ip, $listing)) { - $listing[$ip->ip] = array_merge($listing[$ip->ip], [$ip->port]); - } else { - $listing[$ip->ip] = [$ip->port]; - } - } - - return response()->json($listing); + return Models\Allocation::select('id', 'ip')->where('node_id', $request->input('node'))->whereNull('server_id')->get()->unique('ip')->values()->all(); } /** diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 8f90795c2..1b1079143 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -124,6 +124,12 @@ class UserController extends Controller public function getJson(Request $request) { - return User::select('email')->get()->pluck('email'); + return User::select('id', 'email', 'username', 'name_first', 'name_last') + ->search($request->input('q')) + ->get()->transform(function ($item) { + $item->md5 = md5(strtolower($item->email)); + + return $item; + }); } } diff --git a/app/Http/Middleware/AdminAuthenticate.php b/app/Http/Middleware/AdminAuthenticate.php index c0d74f262..ed286d0b9 100644 --- a/app/Http/Middleware/AdminAuthenticate.php +++ b/app/Http/Middleware/AdminAuthenticate.php @@ -69,9 +69,6 @@ class AdminAuthenticate return abort(403); } - // @TODO: eventually update admin themes - Theme::set('default'); - return $next($request); } } diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index 127055daa..3422088ac 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -136,18 +136,22 @@ class AdminRoutes // Assorted Page Helpers $router->post('/new/get-nodes', [ + 'as' => 'admin.servers.new.get-nodes', 'uses' => 'Admin\ServersController@postNewServerGetNodes', ]); $router->post('/new/get-ips', [ + 'as' => 'admin.servers.new.get-ips', 'uses' => 'Admin\ServersController@postNewServerGetIps', ]); $router->post('/new/service-options', [ + 'as' => 'admin.servers.new.service-options', 'uses' => 'Admin\ServersController@postNewServerServiceOption', ]); $router->post('/new/option-details', [ + 'as' => 'admin.servers.new.option-details', 'uses' => 'Admin\ServersController@postNewServerOptionDetails', ]); // End Assorted Page Helpers diff --git a/app/Models/Server.php b/app/Models/Server.php index 8527e6a14..fa19fda2e 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -29,11 +29,12 @@ use Cache; use Javascript; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; +use Nicolaslopezj\Searchable\SearchableTrait; use Illuminate\Database\Eloquent\SoftDeletes; class Server extends Model { - use Notifiable, SoftDeletes; + use Notifiable, SearchableTrait, SoftDeletes; /** * The table associated with the model. @@ -85,6 +86,22 @@ class Server extends Model 'installed' => 'integer', ]; + protected $searchable = [ + 'columns' => [ + 'servers.name' => 10, + 'servers.username' => 10, + 'servers.uuidShort' => 9, + 'servers.uuid' => 8, + 'users.email' => 6, + 'users.username' => 6, + 'nodes.name' => 2, + ], + 'joins' => [ + 'users' => ['users.id', 'servers.owner_id'], + 'nodes' => ['nodes.id', 'servers.node_id'], + ], + ]; + /** * Returns a single server specified by UUID. * DO NOT USE THIS TO MODIFY SERVER DETAILS OR SAVE THOSE DETAILS. diff --git a/app/Models/User.php b/app/Models/User.php index 131192264..b660e304c 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -30,6 +30,7 @@ use Illuminate\Auth\Authenticatable; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; use Pterodactyl\Exceptions\DisplayException; +use Nicolaslopezj\Searchable\SearchableTrait; use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Foundation\Auth\Access\Authorizable; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; @@ -39,7 +40,7 @@ use Pterodactyl\Notifications\SendPasswordReset as ResetPasswordNotification; class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract { - use Authenticatable, Authorizable, CanResetPassword, Notifiable; + use Authenticatable, Authorizable, CanResetPassword, Notifiable, SearchableTrait; /** * The rules for user passwords. @@ -87,6 +88,16 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac */ protected $hidden = ['password', 'remember_token', 'totp_secret']; + protected $searchable = [ + 'columns' => [ + 'email' => 10, + 'username' => 9, + 'name_first' => 6, + 'name_last' => 6, + 'uuid' => 1, + ], + ]; + /** * Enables or disables TOTP on an account if the token is valid. * diff --git a/composer.json b/composer.json index 40bee8bcb..a95d82df1 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,8 @@ "predis/predis": "1.1.1", "fideloper/proxy": "3.2.0", "laracasts/utilities": "2.1.0", - "lord/laroute": "2.3.0" + "lord/laroute": "2.3.0", + "nicolaslopezj/searchable": "1.9.5" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/composer.lock b/composer.lock index 22e5c4e3b..535af7aa2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "49714983a18ad2bba4759ccde45314c5", - "content-hash": "af8cd5b69f96dd17c1e02afc1ba8e467", + "hash": "6a9656aff0fb3809d27a2a093a810197", + "content-hash": "8affaad10f155172b5079a72015b8bc5", "packages": [ { "name": "aws/aws-sdk-php", @@ -2011,6 +2011,52 @@ ], "time": "2015-11-04 20:07:17" }, + { + "name": "nicolaslopezj/searchable", + "version": "1.9.5", + "source": { + "type": "git", + "url": "https://github.com/nicolaslopezj/searchable.git", + "reference": "1351b1b21ae9be9e0f49f375f56488df839723d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nicolaslopezj/searchable/zipball/1351b1b21ae9be9e0f49f375f56488df839723d4", + "reference": "1351b1b21ae9be9e0f49f375f56488df839723d4", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/database": "4.2.x|~5.0", + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nicolaslopezj\\Searchable\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Lopez", + "email": "nicolaslopezj@me.com" + } + ], + "description": "Eloquent model search trait.", + "keywords": [ + "database", + "eloquent", + "laravel", + "model", + "search", + "searchable" + ], + "time": "2016-12-16 21:23:34" + }, { "name": "nikic/php-parser", "version": "v2.1.1", diff --git a/public/js/laroute.js b/public/js/laroute.js index 633b139f9..350a0c621 100644 --- a/public/js/laroute.js +++ b/public/js/laroute.js @@ -6,7 +6,7 @@ absolute: false, rootUrl: 'http://pterodactyl.app', - routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/get-nodes","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServerGetNodes"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/get-ips","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServerGetIps"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/service-options","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServerServiceOption"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/option-details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServerOptionDetails"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postDatabase"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/container","name":"admin.servers.post.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateContainerDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.post.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerStartup"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/rebuild","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerToggleBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerUpdateBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/suspend","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postSuspendServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/unsuspend","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUnsuspendServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/installed","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postToggleInstall"},{"host":null,"methods":["DELETE"],"uri":"admin\/servers\/view\/{id}\/{force?}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@deleteServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/queuedDeletion","name":"admin.servers.post.queuedDeletion","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postQueuedDeletionHandler"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@postView"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/deallocate\/single\/{allocation}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@deallocateSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/deallocate\/block","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@deallocateBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/alias","name":"admin.nodes.alias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocations.json","name":"admin.nodes.view.allocations","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getAllocationsJson"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocations","name":"admin.nodes.post.allocations","action":"Pterodactyl\Http\Controllers\Admin\NodesController@postAllocations"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/deploy","name":"admin.nodes.deply","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getScript"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@deleteNode"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/{id}\/configurationtoken","name":"admin.nodes.configuration-token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getConfigurationToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}","name":"admin.services.service","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getService"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postService"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}\/configuration","name":"admin.services.service.config","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}\/configuration","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@newOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":"admin.services.option","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOption"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{service}\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":"admin.services.option.variable.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}","name":"admin.services.option.variable","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOptionVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}\/delete","name":"admin.services.option.variable.delete","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/new\/{option?}","name":"admin.services.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/upload\/{option?}","name":"admin.services.packs.uploadForm","action":"Pterodactyl\Http\Controllers\Admin\PackController@uploadForm"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/upload","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@postUpload"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs","name":"admin.services.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@listAll"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/option\/{option}","name":"admin.services.packs.option","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/service\/{service}","name":"admin.services.packs.service","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}","name":"admin.services.packs.edit","action":"Pterodactyl\Http\Controllers\Admin\PackController@edit"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/edit\/{pack}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}\/export\/{archive?}","name":"admin.services.packs.export","action":"Pterodactyl\Http\Controllers\Admin\PackController@export"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], + routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/get-nodes","name":"admin.servers.new.get-nodes","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServerGetNodes"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/get-ips","name":"admin.servers.new.get-ips","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServerGetIps"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/service-options","name":"admin.servers.new.service-options","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServerServiceOption"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/option-details","name":"admin.servers.new.option-details","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServerOptionDetails"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postDatabase"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/container","name":"admin.servers.post.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateContainerDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.post.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerStartup"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/rebuild","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerToggleBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerUpdateBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/suspend","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postSuspendServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/unsuspend","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUnsuspendServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/installed","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postToggleInstall"},{"host":null,"methods":["DELETE"],"uri":"admin\/servers\/view\/{id}\/{force?}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@deleteServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/queuedDeletion","name":"admin.servers.post.queuedDeletion","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postQueuedDeletionHandler"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@postView"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/deallocate\/single\/{allocation}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@deallocateSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/deallocate\/block","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@deallocateBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/alias","name":"admin.nodes.alias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocations.json","name":"admin.nodes.view.allocations","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getAllocationsJson"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocations","name":"admin.nodes.post.allocations","action":"Pterodactyl\Http\Controllers\Admin\NodesController@postAllocations"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/deploy","name":"admin.nodes.deply","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getScript"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@deleteNode"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/{id}\/configurationtoken","name":"admin.nodes.configuration-token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@getConfigurationToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}","name":"admin.services.service","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getService"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postService"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}\/configuration","name":"admin.services.service.config","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}\/configuration","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@newOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":"admin.services.option","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOption"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{service}\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":"admin.services.option.variable.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}","name":"admin.services.option.variable","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOptionVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}\/delete","name":"admin.services.option.variable.delete","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/new\/{option?}","name":"admin.services.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/upload\/{option?}","name":"admin.services.packs.uploadForm","action":"Pterodactyl\Http\Controllers\Admin\PackController@uploadForm"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/upload","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@postUpload"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs","name":"admin.services.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@listAll"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/option\/{option}","name":"admin.services.packs.option","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/service\/{service}","name":"admin.services.packs.service","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}","name":"admin.services.packs.edit","action":"Pterodactyl\Http\Controllers\Admin\PackController@edit"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/edit\/{pack}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}\/export\/{archive?}","name":"admin.services.packs.export","action":"Pterodactyl\Http\Controllers\Admin\PackController@export"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], prefix: '', route : function (name, parameters, route) { diff --git a/public/themes/pterodactyl/css/pterodactyl.css b/public/themes/pterodactyl/css/pterodactyl.css index 342b993b9..13e50047b 100644 --- a/public/themes/pterodactyl/css/pterodactyl.css +++ b/public/themes/pterodactyl/css/pterodactyl.css @@ -132,3 +132,20 @@ td.has-progress { .no-margin { margin: 0 !important; } + +li.select2-results__option--highlighted[aria-selected="false"] > .user-block > .username > a { + color: #fff; +} + +li.select2-results__option--highlighted[aria-selected="false"] > .user-block > .description { + color: #eee; +} + +.img-bordered-xs { + border: 1px solid #d2d6de; + padding: 1px; +} + +span[aria-labelledby="select2-pOwner-container"] { + padding-left: 2px !important; +} diff --git a/resources/themes/pterodactyl/admin/index.blade.php b/resources/themes/pterodactyl/admin/index.blade.php new file mode 100644 index 000000000..0385837af --- /dev/null +++ b/resources/themes/pterodactyl/admin/index.blade.php @@ -0,0 +1,71 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Administration +@endsection + +@section('content-header') +

Administrative OverviewA quick glance at your system.

+ +@endsection + +@section('content') +
+
+
+
+

System Information

+
+
+ @if (Version::isLatestPanel()) + You are running Pterodactyl Panel version {{ Version::getCurrentPanel() }}. Your panel is up-to-date! + @else + Your panel is not up-to-date! The latest version is {{ Version::getPanel() }} and you are currently running version {{ Version::getCurrentPanel() }}. + @endif +
+
+
+
+ +@endsection diff --git a/resources/themes/pterodactyl/admin/servers/index.blade.php b/resources/themes/pterodactyl/admin/servers/index.blade.php new file mode 100644 index 000000000..a9c6deb83 --- /dev/null +++ b/resources/themes/pterodactyl/admin/servers/index.blade.php @@ -0,0 +1,94 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + List Servers +@endsection + +@section('content-header') +

ServersAll servers available on the system.

+ +@endsection + +@section('content') +
+
+
+
+

Server List

+
+
+
+ +
+ + +
+
+
+
+
+
+ + + + + + + + + + + @foreach ($servers as $server) + + + + + + + + + @endforeach + +
IDServer NameOwnerNodeConnection
{{ $server->uuidShort }}{{ $server->name }}{{ $server->user->email }}{{ $server->node->name }} + {{ $server->allocation->alias }}:{{ $server->allocation->port }} + + @if($server->suspended && ! $server->trashed()) + Suspended + @elseif($server->trashed()) + Pending Deletion + @elseif(! $server->installed) + Installing + @else + Active + @endif +
+
+ +
+
+
+@endsection diff --git a/resources/themes/pterodactyl/admin/servers/new.blade.php b/resources/themes/pterodactyl/admin/servers/new.blade.php new file mode 100644 index 000000000..84e45dfa9 --- /dev/null +++ b/resources/themes/pterodactyl/admin/servers/new.blade.php @@ -0,0 +1,230 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + New Server +@endsection + +@section('content-header') +

Create ServerAdd a new server to the panel.

+ +@endsection + +@section('content') +
+
+
+
+
+

Core Details

+
+
+
+ + +

Character limits: a-z A-Z 0-9 _ - . and [Space] (max 200 characters).

+
+
+ + +
+
+
+
+
+
+
+
+ +
+

Allocation Management

+
+
+
+ + +

The location in which this server will be deployed.

+
+
+ + +

The node which this server will be deployed to.

+
+
+ + +

The IP address that this server will be allocated to.

+
+
+ + +

The port that this server will be allocated to.

+
+
+ +
+
+
+
+@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/layouts/admin.blade.php b/resources/themes/pterodactyl/layouts/admin.blade.php new file mode 100644 index 000000000..b3cff34e3 --- /dev/null +++ b/resources/themes/pterodactyl/layouts/admin.blade.php @@ -0,0 +1,198 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} + + + + + + {{ Settings::get('company', 'Pterodactyl') }} - @yield('title') + + + @section('scripts') + {!! Theme::css('vendor/select2/select2.min.css') !!} + {!! Theme::css('vendor/bootstrap/bootstrap.min.css') !!} + {!! Theme::css('vendor/adminlte/admin.min.css') !!} + {!! Theme::css('vendor/adminlte/colors/skin-blue.min.css') !!} + {!! Theme::css('vendor/sweetalert/sweetalert.min.css') !!} + {!! Theme::css('vendor/animate/animate.min.css') !!} + {!! Theme::css('css/pterodactyl.css') !!} + + + + + @show + + +
+
+ + +
+ +
+
+ @yield('content-header') +
+
+
+
+ @if (count($errors) > 0) +
+ @lang('base.validation_error')

+
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+ @endif + @foreach (Alert::getMessages() as $type => $messages) + @foreach ($messages as $message) + + @endforeach + @endforeach +
+
+ @yield('content') +
+
+ + +
+
+ @section('footer-scripts') + {!! Theme::js('js/laroute.js') !!} + {!! Theme::js('js/vendor/jquery/jquery.min.js') !!} + {!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!} + {!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!} + {!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!} + {!! Theme::js('vendor/adminlte/app.min.js') !!} + {!! Theme::js('js/vendor/socketio/socket.io.min.js') !!} + {!! Theme::js('vendor/bootstrap-notify/bootstrap-notify.min.js') !!} + {!! Theme::js('vendor/select2/select2.full.min.js') !!} + @show + + diff --git a/resources/themes/pterodactyl/layouts/master.blade.php b/resources/themes/pterodactyl/layouts/master.blade.php index ce881ada5..b7a7696d1 100644 --- a/resources/themes/pterodactyl/layouts/master.blade.php +++ b/resources/themes/pterodactyl/layouts/master.blade.php @@ -62,14 +62,14 @@ +
  • + +
  • @if(Auth::user()->isRootAdmin())
  • @endif -
  • - -
  • From 58999913ba38b89ac9cb7c39ed3ba797abeb942d Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Thu, 23 Feb 2017 22:52:05 -0500 Subject: [PATCH 02/35] More improvements to add server page. --- .../Controllers/Admin/ServersController.php | 8 +- public/themes/pterodactyl/css/pterodactyl.css | 51 +++++- .../pterodactyl/admin/servers/new.blade.php | 165 ++++++++++++------ 3 files changed, 164 insertions(+), 60 deletions(-) diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 195a66314..ba4e5d1cb 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -120,13 +120,13 @@ class ServersController extends Controller $nodes = Models\Node::with('allocations')->where('location_id', $request->input('location'))->get(); return $nodes->map(function ($item) { $filtered = $item->allocations->map(function($map) { - return collect($map)->only(['ip', 'port']); + return collect($map)->only(['id', 'ip', 'port']); }); - $item->ports = $filtered->unique('ip')->map(function ($map) use ($item) { + $item->ports = $filtered->map(function ($map) use ($item) { return [ - 'ip' => $map['ip'], - 'ports' => $item->allocations->where('ip', $map['ip'])->pluck('port')->all(), + 'id' => $map['id'], + 'text' => $map['ip'] . ':' . $map['port'], ]; })->values(); diff --git a/public/themes/pterodactyl/css/pterodactyl.css b/public/themes/pterodactyl/css/pterodactyl.css index 13e50047b..4a3fe3bf2 100644 --- a/public/themes/pterodactyl/css/pterodactyl.css +++ b/public/themes/pterodactyl/css/pterodactyl.css @@ -141,11 +141,60 @@ li.select2-results__option--highlighted[aria-selected="false"] > .user-block > . color: #eee; } +.select2-search--inline .select2-search__field:focus { + outline: none; + border: 0 !important; +} + .img-bordered-xs { border: 1px solid #d2d6de; padding: 1px; } -span[aria-labelledby="select2-pOwner-container"] { +span[aria-labelledby="select2-pUserId-container"] { padding-left: 2px !important; } + +.callout-slim a { + color: #555 !important; +} + +.callout.callout-info.callout-slim { + border: 1px solid #0097bc !important; + border-left: 5px solid #0097bc !important; + border-right: 5px solid #0097bc !important; + color: #777 !important; + background: transparent !important; +} + +.callout.callout-danger.callout-slim { + border: 1px solid #c23321 !important; + border-left: 5px solid #c23321 !important; + border-right: 5px solid #c23321 !important; + color: #777 !important; + background: transparent !important; +} + +.callout.callout-warning.callout-slim { + border: 1px solid #c87f0a !important; + border-left: 5px solid #c87f0a !important; + border-right: 5px solid #c87f0a !important; + color: #777 !important; + background: transparent !important; +} + +.callout.callout-success.callout-slim { + border: 1px solid #00733e !important; + border-left: 5px solid #00733e !important; + border-right: 5px solid #00733e !important; + color: #777 !important; + background: transparent !important; +} + +.callout.callout-default.callout-slim { + border: 1px solid #eee !important; + border-left: 5px solid #eee !important; + border-right: 5px solid #eee !important; + color: #777 !important; + background: transparent !important; +} diff --git a/resources/themes/pterodactyl/admin/servers/new.blade.php b/resources/themes/pterodactyl/admin/servers/new.blade.php index 84e45dfa9..ad9256e33 100644 --- a/resources/themes/pterodactyl/admin/servers/new.blade.php +++ b/resources/themes/pterodactyl/admin/servers/new.blade.php @@ -36,7 +36,7 @@
    -
    +

    Core Details

    @@ -62,36 +62,29 @@

    Allocation Management

    -
    +

    The location in which this server will be deployed.

    -
    +
    - +

    The node which this server will be deployed to.

    -
    - - -

    The IP address that this server will be allocated to.

    +
    + + +

    The main allocation that will be assigned to this server.

    -
    - - -

    The port that this server will be allocated to.

    +
    + + +

    Additional allocations to assign to this server on creation.

    +
    +
    +
    +
    +

    Resource Management

    +
    +
    +
    + +
    + + MB +
    +
    +
    + +
    + + MB +
    +
    +
    + +
    + + + + +
    +
    +
    + +
    +
    + +
    + + GB +
    +
    +
    + +
    + + % +
    +
    +
    + +
    + + I/O +
    +
    +
    + +
    +
    +
    @endsection @@ -110,10 +170,18 @@ @parent + {!! Theme::js('vendor/lodash/lodash.js') !!} + {!! Theme::js('js/admin/new-server.js') !!} @endsection From bbf9fd12aef3b9f84fb39d2adfd42f3f9abdd476 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 24 Feb 2017 18:23:03 -0500 Subject: [PATCH 04/35] Apply fixes from StyleCI (#325) --- app/Http/Controllers/Admin/ServersController.php | 3 ++- app/Http/Middleware/AdminAuthenticate.php | 1 - app/Models/Server.php | 4 ++-- app/Repositories/ServerRepository.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index be96d3ea4..6372d042a 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -128,8 +128,9 @@ class ServersController extends Controller public function postNewServerGetNodes(Request $request) { $nodes = Models\Node::with('allocations')->where('location_id', $request->input('location'))->get(); + return $nodes->map(function ($item) { - $filtered = $item->allocations->where('server_id', null)->map(function($map) { + $filtered = $item->allocations->where('server_id', null)->map(function ($map) { return collect($map)->only(['id', 'ip', 'port']); }); diff --git a/app/Http/Middleware/AdminAuthenticate.php b/app/Http/Middleware/AdminAuthenticate.php index ed286d0b9..d533fc49d 100644 --- a/app/Http/Middleware/AdminAuthenticate.php +++ b/app/Http/Middleware/AdminAuthenticate.php @@ -24,7 +24,6 @@ namespace Pterodactyl\Http\Middleware; -use Theme; use Closure; use Illuminate\Contracts\Auth\Guard; diff --git a/app/Models/Server.php b/app/Models/Server.php index 106ae000f..252646ba9 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -29,8 +29,8 @@ use Cache; use Javascript; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; -use Nicolaslopezj\Searchable\SearchableTrait; use Illuminate\Database\Eloquent\SoftDeletes; +use Nicolaslopezj\Searchable\SearchableTrait; class Server extends Model { @@ -86,7 +86,7 @@ class Server extends Model 'installed' => 'integer', ]; - protected $searchable = [ + protected $searchable = [ 'columns' => [ 'servers.name' => 10, 'servers.username' => 10, diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index 9d40ecc35..9a2b4eac3 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -268,7 +268,7 @@ class ServerRepository // Add Additional Allocations if (isset($data['allocation_additional']) && is_array($data['allocation_additional'])) { - foreach($data['allocation_additional'] as $allocation) { + foreach ($data['allocation_additional'] as $allocation) { $model = Models\Allocation::where('id', $allocation)->where('node_id', $data['node_id'])->whereNull('server_id')->first(); if (! $model) { continue; From fb21bf9282753567d2645c71153299de7c23ade2 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 25 Feb 2017 00:48:12 -0500 Subject: [PATCH 05/35] Begin implementation of server admin view Currently completed tabs: About, Details, Build Configuration --- .../Controllers/Admin/ServersController.php | 72 +--- app/Http/Routes/AdminRoutes.php | 17 +- app/Repositories/ServerRepository.php | 104 ++--- public/themes/pterodactyl/css/pterodactyl.css | 26 ++ .../pterodactyl/admin/servers/view.blade.php | 390 ++++++++++++++++++ .../pterodactyl/layouts/admin.blade.php | 2 +- 6 files changed, 464 insertions(+), 147 deletions(-) create mode 100644 resources/themes/pterodactyl/admin/servers/view.blade.php diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 6372d042a..2f521804a 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -149,71 +149,13 @@ class ServersController extends Controller })->values(); } - /** - * Returns a JSON tree of all avaliable IPs and Ports on a given node. - * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Contracts\View\View - */ - public function postNewServerGetIps(Request $request) - { - return Models\Allocation::select('id', 'ip')->where('node_id', $request->input('node'))->whereNull('server_id')->get()->unique('ip')->values()->all(); - } - - /** - * Returns a JSON tree of all avaliable options for a given service. - * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Contracts\View\View - */ - public function postNewServerServiceOption(Request $request) - { - if (! $request->input('service')) { - return response()->json([ - 'error' => 'Missing service in request.', - ], 500); - } - - $service = Models\Service::select('executable', 'startup')->where('id', $request->input('service'))->first(); - - return response()->json(Models\ServiceOption::select('id', 'name', 'docker_image')->where('service_id', $request->input('service'))->orderBy('name', 'asc')->get()); - } - - /** - * Returns a JSON tree of all avaliable variables for a given service option. - * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Contracts\View\View - */ - public function postNewServerOptionDetails(Request $request) - { - if (! $request->input('option')) { - return response()->json([ - 'error' => 'Missing option in request.', - ], 500); - } - - $option = Models\ServiceOption::with('variables')->with(['packs' => function ($query) { - $query->where('selectable', true); - }])->findOrFail($request->input('option')); - - return response()->json([ - 'packs' => $option->packs, - 'variables' => $option->variables, - 'exec' => $option->display_executable, - 'startup' => $option->display_startup, - ]); - } - public function postUpdateServerDetails(Request $request, $id) { try { $server = new ServerRepository; - $server->updateDetails($id, [ - 'owner' => $request->input('owner'), - 'name' => $request->input('name'), - 'reset_token' => ($request->input('reset_token', false) === 'on') ? true : false, - ]); + $server->updateDetails($id, $request->intersect([ + 'owner_id', 'name', 'reset_token' + ])); Alert::success('Server details were successfully updated.')->flash(); } catch (DisplayValidationException $ex) { @@ -238,7 +180,7 @@ class ServersController extends Controller { try { $server = new ServerRepository; - $server->updateContainer($id, ['image' => $request->input('docker_image')]); + $server->updateContainer($id, $request->intersect('docker_image')); Alert::success('Successfully updated this server\'s docker image.')->flash(); } catch (DisplayValidationException $ex) { return redirect()->route('admin.servers.view', [ @@ -283,9 +225,9 @@ class ServersController extends Controller { try { $server = new ServerRepository; - $server->changeBuild($id, $request->only([ - 'default', 'add_additional', - 'remove_additional', 'memory', + $server->changeBuild($id, $request->intersect([ + 'allocation_id', 'add_allocations', + 'remove_allocations', 'memory', 'swap', 'io', 'cpu', ])); Alert::success('Server details were successfully updated.')->flash(); diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index 3422088ac..20c528478 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -140,22 +140,6 @@ class AdminRoutes 'uses' => 'Admin\ServersController@postNewServerGetNodes', ]); - $router->post('/new/get-ips', [ - 'as' => 'admin.servers.new.get-ips', - 'uses' => 'Admin\ServersController@postNewServerGetIps', - ]); - - $router->post('/new/service-options', [ - 'as' => 'admin.servers.new.service-options', - 'uses' => 'Admin\ServersController@postNewServerServiceOption', - ]); - - $router->post('/new/option-details', [ - 'as' => 'admin.servers.new.option-details', - 'uses' => 'Admin\ServersController@postNewServerOptionDetails', - ]); - // End Assorted Page Helpers - // View Specific Server $router->get('/view/{id}', [ 'as' => 'admin.servers.view', @@ -170,6 +154,7 @@ class AdminRoutes // Change Server Details $router->post('/view/{id}/details', [ + 'as' => 'admin.servers.view.details', 'uses' => 'Admin\ServersController@postUpdateServerDetails', ]); diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index 9a2b4eac3..756979908 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -352,8 +352,9 @@ class ServerRepository // Validate Fields $validator = Validator::make($data, [ - 'owner' => 'email|exists:users,email', - 'name' => 'regex:([\w .-]{1,200})', + 'owner_id' => 'sometimes|required|numeric|exists:users,id', + 'name' => 'sometimes|required|regex:([\w .-]{1,200})', + 'reset_token' => 'sometimes|required|accepted' ]); // Run validator, throw catchable and displayable exception if it fails. @@ -368,16 +369,15 @@ class ServerRepository $server = Models\Server::with('user')->findOrFail($id); // Update daemon secret if it was passed. - if ((isset($data['reset_token']) && $data['reset_token'] === true) || (isset($data['owner']) && $data['owner'] !== $server->user->email)) { + if (isset($data['reset_token']) || (isset($data['owner_id']) && $data['owner_id'] !== $server->user->id)) { $oldDaemonKey = $server->daemonSecret; $server->daemonSecret = $uuid->generate('servers', 'daemonSecret'); $resetDaemonKey = true; } // Update Server Owner if it was passed. - if (isset($data['owner']) && $data['owner'] !== $server->user->email) { - $newOwner = Models\User::select('id')->where('email', $data['owner'])->first(); - $server->owner_id = $newOwner->id; + if (isset($data['owner_id']) && $data['owner_id'] !== $server->user->id) { + $server->owner_id = $data['owner_id']; } // Update Server Name if it was passed. @@ -431,7 +431,7 @@ class ServerRepository public function updateContainer($id, array $data) { $validator = Validator::make($data, [ - 'image' => 'required|string', + 'docker_image' => 'required|string', ]); // Run validator, throw catchable and displayable exception if it fails. @@ -444,7 +444,7 @@ class ServerRepository try { $server = Models\Server::findOrFail($id); - $server->image = $data['image']; + $server->image = $data['docker_image']; $server->save(); $server->node->guzzleClient([ @@ -479,17 +479,14 @@ class ServerRepository public function changeBuild($id, array $data) { $validator = Validator::make($data, [ - 'default' => [ - 'string', - 'regex:/^(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5])):(\d{1,5})$/', - ], - 'add_additional' => 'nullable|array', - 'remove_additional' => 'nullable|array', - 'memory' => 'integer|min:0', - 'swap' => 'integer|min:-1', - 'io' => 'integer|min:10|max:1000', - 'cpu' => 'integer|min:0', - 'disk' => 'integer|min:0', + 'allocation_id' => 'sometimes|required|exists:allocations,id', + 'add_allocations' => 'sometimes|required|array', + 'remove_allocations' => 'sometimes|required|array', + 'memory' => 'sometimes|required|integer|min:0', + 'swap' => 'sometimes|required|integer|min:-1', + 'io' => 'sometimes|required|integer|min:10|max:1000', + 'cpu' => 'sometimes|required|integer|min:0', + 'disk' => 'sometimes|required|integer|min:0', ]); // Run validator, throw catchable and displayable exception if it fails. @@ -503,43 +500,33 @@ class ServerRepository try { $server = Models\Server::with('allocation', 'allocations')->findOrFail($id); $newBuild = []; + $newAllocations = []; - if (isset($data['default'])) { - list($ip, $port) = explode(':', $data['default']); - if ($ip !== $server->allocation->ip || (int) $port !== $server->allocation->port) { - $selection = $server->allocations->where('ip', $ip)->where('port', $port)->first(); + if (isset($data['allocation_id'])) { + if ((int) $data['allocation_id'] !== $server->allocation_id) { + $selection = $server->allocations->where('id', $data['allocation_id'])->first(); if (! $selection) { - throw new DisplayException('The requested default connection (' . $ip . ':' . $port . ') is not allocated to this server.'); + throw new DisplayException('The requested default connection is not allocated to this server.'); } $server->allocation_id = $selection->id; - $newBuild['default'] = [ - 'ip' => $ip, - 'port' => (int) $port, - ]; + $newBuild['default'] = ['ip' => $selection->ip, 'port' => $selection->port]; - // Re-Run to keep updated for rest of function $server->load('allocation'); } } $newPorts = false; // Remove Assignments - if (isset($data['remove_additional'])) { - foreach ($data['remove_additional'] as $id => $combo) { - list($ip, $port) = explode(':', $combo); - // Invalid, not worth killing the whole thing, we'll just skip over it. - if (! filter_var($ip, FILTER_VALIDATE_IP) || ! preg_match('/^(\d{1,5})$/', $port)) { - break; - } - + if (isset($data['remove_allocations'])) { + foreach ($data['remove_allocations'] as $allocation) { // Can't remove the assigned IP/Port combo - if ($ip === $server->allocation->ip && (int) $port === (int) $server->allocation->port) { - break; + if ((int) $allocation === $server->allocation_id) { + continue; } $newPorts = true; - $server->allocations->where('ip', $ip)->where('port', $port)->update([ + Models\Allocation::where('id', $allocation)->where('server_id', $server->id)->update([ 'server_id' => null, ]); } @@ -548,21 +535,15 @@ class ServerRepository } // Add Assignments - if (isset($data['add_additional'])) { - foreach ($data['add_additional'] as $id => $combo) { - list($ip, $port) = explode(':', $combo); - // Invalid, not worth killing the whole thing, we'll just skip over it. - if (! filter_var($ip, FILTER_VALIDATE_IP) || ! preg_match('/^(\d{1,5})$/', $port)) { - break; - } - - // Don't allow double port assignments - if ($server->allocations->where('port', $port)->count() !== 0) { - break; + if (isset($data['add_allocations'])) { + foreach ($data['add_allocations'] as $allocation) { + $model = Models\Allocation::where('id', $allocation)->whereNull('server_id')->first(); + if (! $model) { + continue; } $newPorts = true; - Models\Allocation::where('ip', $ip)->where('port', $port)->whereNull('server_id')->update([ + $model->update([ 'server_id' => $server->id, ]); } @@ -570,18 +551,10 @@ class ServerRepository $server->load('allocations'); } - // Loop All Assignments - $additionalAssignments = []; - foreach ($server->allocations as &$assignment) { - if (array_key_exists((string) $assignment->ip, $additionalAssignments)) { - array_push($additionalAssignments[(string) $assignment->ip], (int) $assignment->port); - } else { - $additionalAssignments[(string) $assignment->ip] = [(int) $assignment->port]; - } - } - - if ($newPorts === true) { - $newBuild['ports|overwrite'] = $additionalAssignments; + if ($newPorts) { + $newBuild['ports|overwrite'] = $server->allocations->groupBy('ip')->map(function ($item) { + return $item->pluck('port'); + })->toArray(); } // @TODO: verify that server can be set to this much memory without @@ -617,6 +590,7 @@ class ServerRepository // This won't be committed unless the HTTP request succeedes anyways $server->save(); + dd($newBuild); if (! empty($newBuild)) { $server->node->guzzleClient([ 'X-Access-Server' => $server->uuid, @@ -630,7 +604,7 @@ class ServerRepository DB::commit(); - return true; + return $server; } catch (TransferException $ex) { DB::rollBack(); throw new DisplayException('An error occured while attempting to update the configuration.', $ex); diff --git a/public/themes/pterodactyl/css/pterodactyl.css b/public/themes/pterodactyl/css/pterodactyl.css index 4a3fe3bf2..497c49324 100644 --- a/public/themes/pterodactyl/css/pterodactyl.css +++ b/public/themes/pterodactyl/css/pterodactyl.css @@ -198,3 +198,29 @@ span[aria-labelledby="select2-pUserId-container"] { color: #777 !important; background: transparent !important; } + +.tab-pane .box-footer { + margin: 0 -10px -10px; +} + +.select2-container{ width: 100% !important; } + +.nav-tabs-custom > .nav-tabs > li:hover { + border-top-color:#3c8dbc; +} + +.nav-tabs-custom > .nav-tabs > li.active.tab-danger, .nav-tabs-custom > .nav-tabs > li.tab-danger:hover { + border-top-color: #c23321; +} + +.nav-tabs-custom > .nav-tabs > li.active.tab-success, .nav-tabs-custom > .nav-tabs > li.tab-success:hover { + border-top-color: #00733e; +} + +.nav-tabs-custom > .nav-tabs > li.active.tab-info, .nav-tabs-custom > .nav-tabs > li.tab-info:hover { + border-top-color: #0097bc; +} + +.nav-tabs-custom > .nav-tabs > li.active.tab-warning, .nav-tabs-custom > .nav-tabs > li.tab-warning:hover { + border-top-color: #c87f0a; +} diff --git a/resources/themes/pterodactyl/admin/servers/view.blade.php b/resources/themes/pterodactyl/admin/servers/view.blade.php new file mode 100644 index 000000000..85a74536c --- /dev/null +++ b/resources/themes/pterodactyl/admin/servers/view.blade.php @@ -0,0 +1,390 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Manage Server: {{ $server->name }} +@endsection + +@section('content-header') +

    {{ $server->name }}{{ $server->uuid }}

    + +@endsection + +@section('content') + @if($server->suspended && ! $server->trashed()) +
    + This server is suspended and has no user access. Processes cannot be started and files cannot be modified. All API access is disabled unless using a master token. +
    + @elseif($server->trashed()) +
    + This server is marked for deletion {{ Carbon::parse($server->deleted_at)->addMinutes(env('APP_DELETE_MINUTES', 10))->diffForHumans() }}. If you want to cancel this action simply click the button below. +

    +
    + + + + {!! csrf_field() !!} +
    +
    + @endif + @if(! $server->installed) +
    + This server is still running through the install process and is not avaliable for use just yet. This message will disappear once this process is completed. +
    + @elseif($server->installed === 2) +
    + This server failed to install properly. You should delete it and try to create it again or check the daemon logs. +
    + @endif +
    +
    + +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/layouts/admin.blade.php b/resources/themes/pterodactyl/layouts/admin.blade.php index b3cff34e3..568b60acc 100644 --- a/resources/themes/pterodactyl/layouts/admin.blade.php +++ b/resources/themes/pterodactyl/layouts/admin.blade.php @@ -67,7 +67,7 @@
  • -
  • +
  • From 9f54ff236ae418650cc93798a5df258c2cb84570 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 25 Feb 2017 14:14:07 -0500 Subject: [PATCH 06/35] Add back manage and delete tabs to server view Will come back to deal with Startup and Database tabs at a later date. --- .../themes/pterodactyl/js/admin/functions.js | 23 ++++++ .../pterodactyl/admin/servers/view.blade.php | 75 ++++++++++++++++++- .../pterodactyl/layouts/admin.blade.php | 1 + resources/views/layouts/admin.blade.php | 4 - 4 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 public/themes/pterodactyl/js/admin/functions.js diff --git a/public/themes/pterodactyl/js/admin/functions.js b/public/themes/pterodactyl/js/admin/functions.js new file mode 100644 index 000000000..26115cd46 --- /dev/null +++ b/public/themes/pterodactyl/js/admin/functions.js @@ -0,0 +1,23 @@ +// Copyright (c) 2015 - 2017 Dane Everitt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +$.urlParam=function(name){var results=new RegExp("[\\?&]"+name+"=([^&#]*)").exec(decodeURIComponent(window.location.href));if(results==null){return null}else{return results[1]||0}};function getPageName(url){var index=url.lastIndexOf("/")+1;var filenameWithExtension=url.substr(index);var filename=filenameWithExtension.split(".")[0];return filename} +// Remeber Active Tab and Navigate to it on Reload +for(var queryParameters={},queryString=location.search.substring(1),re=/([^&=]+)=([^&]*)/g,m;m=re.exec(queryString);)queryParameters[decodeURIComponent(m[1])]=decodeURIComponent(m[2]);$("a[data-toggle='tab']").click(function(){queryParameters.tab=$(this).attr("href").substring(1),window.history.pushState(null,null,location.pathname+"?"+$.param(queryParameters))}); +if($.urlParam('tab') != null){$('.nav.nav-tabs a[href="#' + $.urlParam('tab') + '"]').tab('show');} diff --git a/resources/themes/pterodactyl/admin/servers/view.blade.php b/resources/themes/pterodactyl/admin/servers/view.blade.php index 85a74536c..5818f9510 100644 --- a/resources/themes/pterodactyl/admin/servers/view.blade.php +++ b/resources/themes/pterodactyl/admin/servers/view.blade.php @@ -293,13 +293,70 @@ {{-- End Database / Start Manage --}} @if($server->installed !== 2)
    - Manage +
    +
    +
    + {!! csrf_field() !!} + +

    This will toggle the install status for the server.

    +
    +
    +
    +
    + {!! csrf_field() !!} + +

    This will trigger a rebuild of the server container when it next starts up. This is useful if you modified the server configuration file manually, or something just didn't work out correctly.

    +
    +
    +
    + @if(! $server->suspended) +
    + {!! csrf_field() !!} + +

    This will suspend the server, stop any running processes, and immediately block the user from being able to access their files or otherwise manage the server through the panel or API.

    +
    + @else +
    + {!! csrf_field() !!} + +

    This will unsuspend the server and restore normal user access.

    +
    + @endif +
    +
    @endif {{-- End Manage / Start Delete --}} @if(! $server->trashed())
    - Delete +
    + @if($server->installed) +
    +
    + {!! csrf_field() !!} + {!! method_field('DELETE') !!} + +
    +

    +

    + Deleting a server is an irreversible action. All data will be immediately removed relating to this server. +
    +

    +
    + @endif +
    +
    + {!! csrf_field() !!} + {!! method_field('DELETE') !!} + +
    +

    +

    + This is the same as deleting a server, however, if an error is returned by the daemon it is ignored and the server is still removed from the panel. +
    +

    +
    +
    @endif {{-- End Delete --}} @@ -312,6 +369,20 @@ @section('footer-scripts') @parent +@endsection diff --git a/resources/themes/pterodactyl/admin/nodes/view/allocation.blade.php b/resources/themes/pterodactyl/admin/nodes/view/allocation.blade.php new file mode 100644 index 000000000..ac385e608 --- /dev/null +++ b/resources/themes/pterodactyl/admin/nodes/view/allocation.blade.php @@ -0,0 +1,245 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + {{ $node->name }}: Allocations +@endsection + +@section('content-header') +

    {{ $node->name }}Control allocations available for servers on this node.

    + +@endsection + +@section('content') + +
    +
    +
    +
    +

    Existing Allocations

    +
    +
    + + + + + + + + + @foreach($node->allocations as $allocation) + + + + + + + + @endforeach +
    IP Address IP AliasPortAssigned To
    {{ $allocation->ip }} + + + {{ $allocation->port }} + @if(! is_null($allocation->server)) + {{ $allocation->server->name }} + @endif + + @if(is_null($allocation->server_id)) + + @else + + @endif +
    +
    + +
    +
    +
    +
    +
    +
    +

    Assign New Allocations

    +
    +
    +
    + +
    + +

    Enter an IP address to assign ports to here.

    +
    +
    +
    + +
    + +

    If you would like to assign a default alias to these allocations enter it here.

    +
    +
    +
    + +
    + +

    Enter individual ports or port ranges here separated by commas or spaces.

    +
    +
    +
    + +
    +
    +
    +
    + +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php b/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php new file mode 100644 index 000000000..daa42fd40 --- /dev/null +++ b/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php @@ -0,0 +1,102 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + {{ $node->name }}: Configuration +@endsection + +@section('content-header') +

    {{ $node->name }}Your daemon configuration file.

    + +@endsection + +@section('content') + +
    +
    +
    +
    +

    Configuration File

    +
    +
    +
    {{ $node->getConfigurationAsJson(true) }}
    +
    + +
    +
    +
    +
    +
    +

    Auto-Deploy

    +
    +
    +

    To simplify the configuration of nodes it is possible to fetch the config from the panel. A token is required for this process. The button below will generate a token and provide you with the commands necessary for automatic configuration of the node. Tokens are only valid for 5 minutes.

    +
    + +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/nodes/view/index.blade.php b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php new file mode 100644 index 000000000..9af1e6fad --- /dev/null +++ b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php @@ -0,0 +1,143 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + {{ $node->name }} +@endsection + +@section('content-header') +

    {{ $node->name }}A quick overview of your node.

    + +@endsection + +@section('content') + +
    +
    +
    +
    +

    Information

    +
    +
    + + + + + + + + + + + + + +
    Daemon Version (Latest: {{ Version::getDaemon() }})
    System Information
    Total CPU Cores
    +
    +
    +
    +
    +
    +
    +

    At-a-Glance

    +
    +
    +
    +
    +
    + +
    + Disk Space Allocated + {{ $stats['disk']['value'] }} Mb +
    +
    +
    +
    +
    +
    +
    +
    + +
    + Memory Allocated + {{ $stats['memory']['value'] }} Mb +
    +
    +
    +
    +
    +
    +
    +
    + +
    + Total Servers + {{ $node->servers_count }} +
    +
    +
    +
    +
    +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php b/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php new file mode 100644 index 000000000..d7ebcbabe --- /dev/null +++ b/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php @@ -0,0 +1,91 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + {{ $node->name }}: Servers +@endsection + +@section('content-header') +

    {{ $node->name }}All servers currently assigned to this node.

    + +@endsection + +@section('content') + +
    +
    +
    +
    +

    Process Manager

    +
    +
    + + + + + + + + + + + + @foreach($node->servers as $server) + + + + + + + + + + + @endforeach +
    IDServer NameOwnerServiceMemoryDiskCPUStatus
    {{ $server->uuidShort }}{{ $server->name }}{{ $server->user->email }}{{ $server->service->name }}NaN / {{ $server->memory === 0 ? '∞' : $server->memory }} MB{{ $server->disk }} MBNaN %NaN
    +
    +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + {!! Theme::js('js/admin/node/view-servers.js') !!} +@endsection diff --git a/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php b/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php new file mode 100644 index 000000000..97261f991 --- /dev/null +++ b/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php @@ -0,0 +1,224 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + {{ $node->name }}: Settings +@endsection + +@section('content-header') +

    {{ $node->name }}Configure your node settings.

    + +@endsection + +@section('content') + +
    +
    +
    +
    +
    +

    Settings

    +
    +
    +
    + +
    + +

    Character limits: a-zA-Z0-9_.- and [Space] (min 1, max 100 characters).

    +
    +
    +
    + +
    + +
    +
    +
    + +
    + public) === '1') ? 'checked' : '' }} id="public_1" checked>
    + public) === '0') ? 'checked' : '' }} id="public_0"> +
    +
    +
    + +
    + +
    +

    Please enter domain name (e.g node.example.com) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node. + Why? +

    +
    +
    + +
    +
    + scheme) === 'https') ? 'checked' : '' }}/> +
    +
    + scheme) === 'http') ? 'checked' : '' }}/> +
    +
    +

    You should always leave SSL enabled for nodes. Disabling SSL could allow a malicious user to intercept traffic between the panel and the daemon potentially exposing sensitive information.

    +
    + +
    +
    +
    +
    +
    +
    +

    Allocation Limits

    +
    +
    +
    +
    +
    + +
    + + MB +
    +
    +
    + +
    + + % +
    +
    +
    +

    Enter the total amount of memory available on this node for allocation to servers. You may also provide a percentage that can allow allocation of more than the defined memory.

    +
    +
    +
    +
    + +
    + + MB +
    +
    +
    + +
    + + % +
    +
    +
    +

    Enter the total amount of disk space available on this node for server allocation. You may also provide a percentage that will determine the amount of disk space over the set limit to allow.

    +
    +
    +
    +
    +
    +
    +
    +

    General Configuration

    +
    +
    +
    + +
    + + MB +
    +

    Enter the maximum size of files that can be uploaded through the web-based file manager.

    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +

    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.

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Save Settings

    +
    +
    +
    +
    + +
    +

    Resetting the daemon master key will void any request coming from the old key. This key is used for all sensitive operations on the daemon including server creation and deletion. We suggest changing this key regularly for security.

    +
    +
    + +
    +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/servers/index.blade.php b/resources/themes/pterodactyl/admin/servers/index.blade.php index a9c6deb83..b311424f7 100644 --- a/resources/themes/pterodactyl/admin/servers/index.blade.php +++ b/resources/themes/pterodactyl/admin/servers/index.blade.php @@ -40,7 +40,7 @@
    - +
    diff --git a/resources/themes/pterodactyl/layouts/admin.blade.php b/resources/themes/pterodactyl/layouts/admin.blade.php index e44aeac1a..7016fdc5b 100644 --- a/resources/themes/pterodactyl/layouts/admin.blade.php +++ b/resources/themes/pterodactyl/layouts/admin.blade.php @@ -90,15 +90,15 @@ Settings -
  • SERVER MANAGEMENT
  • +
  • MANAGEMENT
  • List Servers
  • -
  • - - Create Server +
  • + + List Nodes
  • From 2efd6865e330b8b45fdf8865d9d16aa3f6d483cd Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Fri, 3 Mar 2017 23:25:34 +0100 Subject: [PATCH 10/35] fix rethemed settings title --- resources/themes/pterodactyl/admin/settings.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/pterodactyl/admin/settings.blade.php b/resources/themes/pterodactyl/admin/settings.blade.php index 815779849..5bc8a2ad3 100644 --- a/resources/themes/pterodactyl/admin/settings.blade.php +++ b/resources/themes/pterodactyl/admin/settings.blade.php @@ -20,7 +20,7 @@ @extends('layouts.admin') @section('title') - Administration + Settings @endsection @section('content-header') From b91e3d95f87a72e3cfaad2befa23a659022eb858 Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Fri, 3 Mar 2017 23:42:58 +0100 Subject: [PATCH 11/35] fix revealing module and jquery3 of 2fa-modal --- public/themes/pterodactyl/js/frontend/2fa-modal.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/public/themes/pterodactyl/js/frontend/2fa-modal.js b/public/themes/pterodactyl/js/frontend/2fa-modal.js index 935bd0f59..022ece2ff 100644 --- a/public/themes/pterodactyl/js/frontend/2fa-modal.js +++ b/public/themes/pterodactyl/js/frontend/2fa-modal.js @@ -37,7 +37,7 @@ var TwoFactorModal = (function () { }).done(function (data) { var image = new Image(); image.src = data.qrImage; - $(image).load(function () { + $(image).on('load', function () { $('#hide_img_load').slideUp(function () { $('#qr_image_insert').attr('src', image.src).slideDown(); }); @@ -85,7 +85,6 @@ var TwoFactorModal = (function () { bindListeners(); } } - -}); +})(); TwoFactorModal.init(); From 2854a55aa2a191e77aa579bc0b1ce9686d8332bf Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 3 Mar 2017 17:50:45 -0500 Subject: [PATCH 12/35] Fix server view to use owner username and named route locations --- resources/themes/pterodactyl/admin/servers/index.blade.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/themes/pterodactyl/admin/servers/index.blade.php b/resources/themes/pterodactyl/admin/servers/index.blade.php index b311424f7..820ca47df 100644 --- a/resources/themes/pterodactyl/admin/servers/index.blade.php +++ b/resources/themes/pterodactyl/admin/servers/index.blade.php @@ -63,9 +63,9 @@ @foreach ($servers as $server) {{ $server->uuidShort }} - {{ $server->name }} - {{ $server->user->email }} - {{ $server->node->name }} + {{ $server->name }} + {{ $server->user->username }} + {{ $server->node->name }} {{ $server->allocation->alias }}:{{ $server->allocation->port }} From fd5b74c87383a9f41075afbce0c4b12140c13b1e Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 3 Mar 2017 17:53:35 -0500 Subject: [PATCH 13/35] Use usernames for @schrej --- app/Http/Controllers/Admin/NodesController.php | 2 +- .../themes/pterodactyl/admin/nodes/view/servers.blade.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Admin/NodesController.php b/app/Http/Controllers/Admin/NodesController.php index 8ee9e2df8..ee4a58066 100644 --- a/app/Http/Controllers/Admin/NodesController.php +++ b/app/Http/Controllers/Admin/NodesController.php @@ -211,7 +211,7 @@ class NodesController extends Controller */ public function viewServers(Request $request, $id) { - $node = Models\Node::with('servers.user', 'servers.service', 'servers.allocations')->findOrFail($id); + $node = Models\Node::with('servers.user', 'servers.service', 'servers.option')->findOrFail($id); Javascript::put([ 'node' => collect($node->makeVisible('daemonSecret'))->only(['scheme', 'fqdn', 'daemonListen', 'daemonSecret']), ]); diff --git a/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php b/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php index d7ebcbabe..519b5fbbe 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php @@ -70,8 +70,8 @@ {{ $server->uuidShort }} {{ $server->name }} - {{ $server->user->email }} - {{ $server->service->name }} + {{ $server->user->username }} + {{ $server->service->name }} ({{ $server->option->name }}) NaN / {{ $server->memory === 0 ? '∞' : $server->memory }} MB {{ $server->disk }} MB NaN % From 6df573e50c5f44dd5e4920bee7bcc2a7ce502808 Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Sat, 4 Mar 2017 00:14:21 +0100 Subject: [PATCH 14/35] retheme admin users list --- app/Http/Controllers/Admin/UserController.php | 8 +- .../pterodactyl/admin/users/index.blade.php | 84 +++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 resources/themes/pterodactyl/admin/users/index.blade.php diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 1b1079143..0de02eca9 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -47,8 +47,14 @@ class UserController extends Controller // @TODO: implement nicolaslopezj/searchable to clean up this disaster. public function getIndex(Request $request) { + $users = User::withCount('servers'); + + if (! is_null($request->input('query'))) { + $users->search($request->input('query')); + } + return view('admin.users.index', [ - 'users' => User::paginate(25), + 'users' => $users->paginate(25), ]); } diff --git a/resources/themes/pterodactyl/admin/users/index.blade.php b/resources/themes/pterodactyl/admin/users/index.blade.php new file mode 100644 index 000000000..3832c0374 --- /dev/null +++ b/resources/themes/pterodactyl/admin/users/index.blade.php @@ -0,0 +1,84 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + List Users +@endsection + +@section('content-header') +

    UsersAll registered users on the system.

    + +@endsection + +@section('content') +
    +
    +
    +
    +

    User List

    +
    + +
    + +
    + + +
    +
    + +
    +
    +
    + + + + + + + + + + + @foreach ($users as $user) + + + + + + + + + @endforeach + +
    ID + Email + Client NameUsernameServers
    {{ $user->id }}{{ $user->email }}{{ $user->name_last }}, {{ $user->name_first }}{{ $user->username }}{{ $user->servers_count }}
    +
    + +
    +
    +
    +@endsection From e331157f53ebac73b280a12083f00e977860180e Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Sat, 4 Mar 2017 00:20:17 +0100 Subject: [PATCH 15/35] add users menu link to new admin layout rename server list to servers rename node list to nodes --- resources/themes/pterodactyl/layouts/admin.blade.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/resources/themes/pterodactyl/layouts/admin.blade.php b/resources/themes/pterodactyl/layouts/admin.blade.php index 7016fdc5b..72238ce48 100644 --- a/resources/themes/pterodactyl/layouts/admin.blade.php +++ b/resources/themes/pterodactyl/layouts/admin.blade.php @@ -93,12 +93,17 @@
  • MANAGEMENT
  • - List Servers + Servers
  • - List Nodes + Nodes + +
  • +
  • + + Users
  • From ae980f90206b6971b6ecb04e141a40a2b864715b Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Sat, 4 Mar 2017 01:10:03 +0100 Subject: [PATCH 16/35] retheme admin user view --- .../pterodactyl/admin/users/view.blade.php | 197 ++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 resources/themes/pterodactyl/admin/users/view.blade.php diff --git a/resources/themes/pterodactyl/admin/users/view.blade.php b/resources/themes/pterodactyl/admin/users/view.blade.php new file mode 100644 index 000000000..7b1dbeefa --- /dev/null +++ b/resources/themes/pterodactyl/admin/users/view.blade.php @@ -0,0 +1,197 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Manager User: {{ $user->username }} +@endsection + +@section('content-header') +

    {{ $user->name_first }} {{ $user->name_last}}{{ $user->username }}

    + +@endsection + +@section('content') +
    +
    +
    +
    +

    Identity

    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    Password

    +
    +
    +
    + +
    + +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +

    Permissions

    +
    +
    +
    +
    + +
    + +

    Setting this to 'Yes' gives a user full administrative access.

    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    Associated Servers

    +
    +
    + + + + + + + + + + + + @foreach($user->servers as $server) + + + + + + + + @endforeach + +
    IdentifierServer NameNode
    {{ $server->uuidShort }}{{ $server->name }}{{ $server->node->name }}@if($server->suspended === 0)Active@elseSuspended@endif
    +
    + +
    +
    +
    +
    +
    +

    Delete User

    +
    +
    +
    Warning! There most be no servers associated with this account in order for it to be deleted.
    +

    +
    + {!! method_field('DELETE') !!} + {!! csrf_field() !!} + +
    +
    + +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection From d1811822f36742b8d21b7d83765df97d9b6baf9a Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Sat, 4 Mar 2017 01:44:52 +0100 Subject: [PATCH 17/35] fix form on admin user view --- .../pterodactyl/admin/users/view.blade.php | 55 +++++++------------ 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/resources/themes/pterodactyl/admin/users/view.blade.php b/resources/themes/pterodactyl/admin/users/view.blade.php index 7b1dbeefa..146a8c664 100644 --- a/resources/themes/pterodactyl/admin/users/view.blade.php +++ b/resources/themes/pterodactyl/admin/users/view.blade.php @@ -34,12 +34,12 @@ @section('content')
    -
    -
    -
    -

    Identity

    -
    -
    + +
    +
    +
    +

    Identity

    +
    @@ -68,17 +68,15 @@
    - -
    -
    -
    -
    -
    -

    Password

    -
    +
    +
    +
    +
    +

    Password

    +
    @@ -91,19 +89,13 @@
    - - -
    -
    -
    -
    -
    -

    Permissions

    -
    +
    +
    +
    +
    +

    Permissions

    +
    @@ -116,13 +108,9 @@
    - - +
    -
    +
    @@ -169,7 +157,6 @@
    -
    From 23dfcbd7bc6f19b84fd3d4ac4f07a40fa198d726 Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Sat, 4 Mar 2017 01:45:03 +0100 Subject: [PATCH 18/35] retheme admin create user page --- .../pterodactyl/admin/users/new.blade.php | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 resources/themes/pterodactyl/admin/users/new.blade.php diff --git a/resources/themes/pterodactyl/admin/users/new.blade.php b/resources/themes/pterodactyl/admin/users/new.blade.php new file mode 100644 index 000000000..c10029127 --- /dev/null +++ b/resources/themes/pterodactyl/admin/users/new.blade.php @@ -0,0 +1,144 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Create User +@endsection + +@section('content-header') +

    Create UserAdd a new user to the system.

    + +@endsection + +@section('content') +
    +
    +
    +
    +
    +

    Identity

    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +

    Permissions

    +
    +
    +
    + +
    + +

    Setting this to 'Yes' gives a user full administrative access.

    +
    +
    +
    +
    +
    +
    +
    +
    +

    Password

    +
    +
    +
    +

    Providing a user password is optional. New user emails prompt users to create a password the first time they login. If a password is provided here you will need to find a different method of providing it to the user.

    +
    + +
    + +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection From 61d8332e934b454ae2e34100efa1989d802f89b7 Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Sat, 4 Mar 2017 01:47:39 +0100 Subject: [PATCH 19/35] make new user and view user consistent --- .../pterodactyl/admin/users/new.blade.php | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/resources/themes/pterodactyl/admin/users/new.blade.php b/resources/themes/pterodactyl/admin/users/new.blade.php index c10029127..ada012874 100644 --- a/resources/themes/pterodactyl/admin/users/new.blade.php +++ b/resources/themes/pterodactyl/admin/users/new.blade.php @@ -41,34 +41,29 @@

    Identity

    -
    -
    - -
    - -
    -
    -
    - -
    - -
    +
    + +
    +
    -
    -
    - -
    - -
    +
    + +
    +
    -
    - -
    - -
    +
    +
    + +
    + +
    +
    +
    + +
    +
    -
    diff --git a/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php b/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php index daa42fd40..536b3e384 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php @@ -43,7 +43,6 @@
  • Configuration
  • Allocation
  • Servers
  • -
  • Delete
  • diff --git a/resources/themes/pterodactyl/admin/nodes/view/index.blade.php b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php index 9af1e6fad..de875c678 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/index.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/index.blade.php @@ -42,32 +42,52 @@
  • Configuration
  • Allocation
  • Servers
  • -
  • Delete
  • -
    -
    -

    Information

    +
    +
    +
    +
    +

    Information

    +
    +
    + + + + + + + + + + + + + +
    Daemon Version (Latest: {{ Version::getDaemon() }})
    System Information
    Total CPU Cores
    +
    +
    -
    - - - - - - - - - - - - - -
    Daemon Version (Latest: {{ Version::getDaemon() }})
    System Information
    Total CPU Cores
    +
    +
    +
    +

    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.

    +
    + +
    diff --git a/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php b/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php index 519b5fbbe..0033dac2e 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/servers.blade.php @@ -43,7 +43,6 @@
  • Configuration
  • Allocation
  • Servers
  • -
  • Delete
  • diff --git a/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php b/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php index 97261f991..74e31a5c4 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/settings.blade.php @@ -43,7 +43,6 @@
  • Configuration
  • Allocation
  • Servers
  • -
  • Delete
  • From d38f89a4685bb98076da865ba452b960ac04a2d6 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 3 Mar 2017 23:14:23 -0500 Subject: [PATCH 21/35] Cleanup node routes, cleanup remote token --- .../Controllers/Admin/NodesController.php | 125 ++++++++---------- .../Controllers/Remote/RemoteController.php | 13 +- app/Http/Routes/AdminRoutes.php | 53 +++----- app/Models/NodeConfigurationToken.php | 10 ++ ...3_224254_UpdateNodeConfigTokensColumns.php | 42 ++++++ .../admin/nodes/view/configuration.blade.php | 2 +- 6 files changed, 131 insertions(+), 114 deletions(-) create mode 100644 database/migrations/2017_03_03_224254_UpdateNodeConfigTokensColumns.php diff --git a/app/Http/Controllers/Admin/NodesController.php b/app/Http/Controllers/Admin/NodesController.php index ee4a58066..023c52e3e 100644 --- a/app/Http/Controllers/Admin/NodesController.php +++ b/app/Http/Controllers/Admin/NodesController.php @@ -26,6 +26,7 @@ namespace Pterodactyl\Http\Controllers\Admin; use DB; use Log; +use Hash; use Alert; use Carbon; use Validator; @@ -107,21 +108,6 @@ class NodesController extends Controller return redirect()->route('admin.nodes.new')->withInput(); } - public function getView(Request $request, $id) - { - $node = Models\Node::with( - 'servers.user', 'servers.service', - 'servers.allocations', 'location' - )->findOrFail($id); - $node->setRelation('allocations', $node->allocations()->with('server')->paginate(40)); - - return view('admin.nodes.view', [ - 'node' => $node, - 'stats' => Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node_id', $node->id)->first(), - 'locations' => Models\Location::all(), - ]); - } - /** * Shows the index overview page for a specific node. * @@ -221,36 +207,35 @@ class NodesController extends Controller ]); } - public function postView(Request $request, $id) + /** + * Updates settings for a node. + * + * @param Request $request + * @param integer $node + * @return \Illuminate\Http\RedirectResponse + */ + public function updateSettings(Request $request, $id) { + $repo = new NodeRepository; + try { - $node = new NodeRepository; - $node->update($id, $request->only([ - 'name', 'location_id', 'public', - 'fqdn', 'scheme', 'memory', - 'memory_overallocate', 'disk', - 'disk_overallocate', 'upload_size', + $repo->update($id, $request->intersect([ + 'name', 'location_id', 'public', 'fqdn', 'scheme', 'memory', + 'memory_overallocate', 'disk', 'disk_overallocate', 'upload_size', 'daemonSFTP', 'daemonListen', 'reset_secret', ])); - Alert::success('Successfully update this node\'s information. If you changed any daemon settings you will need to restart it now.')->flash(); - return redirect()->route('admin.nodes.view', [ - 'id' => $id, - 'tab' => 'tab_settings', - ]); - } catch (DisplayValidationException $e) { - return redirect()->route('admin.nodes.view', $id)->withErrors(json_decode($e->getMessage()))->withInput(); - } catch (DisplayException $e) { - Alert::danger($e->getMessage())->flash(); - } catch (\Exception $e) { - Log::error($e); + Alert::success('Successfully updated this node\'s information. If you changed any daemon settings you will need to restart it now.')->flash(); + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.nodes.view.settings', $id)->withErrors(json_decode($ex->getMessage()))->withInput(); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); Alert::danger('An unhandled exception occured while attempting to edit this node. Please try again.')->flash(); } - return redirect()->route('admin.nodes.view', [ - 'id' => $id, - 'tab' => 'tab_settings', - ])->withInput(); + return redirect()->route('admin.nodes.view.settings', $id)->withInput(); } /** @@ -259,7 +244,7 @@ class NodesController extends Controller * @param Request $request * @param integer $node * @param integer $allocation [description] - * @return mixed + * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse */ public function allocationRemoveSingle(Request $request, $node, $allocation) { @@ -278,7 +263,7 @@ class NodesController extends Controller * * @param Request $request * @param integer $node - * @return mixed + * @return \Illuminate\Http\RedirectResponse */ public function allocationRemoveBlock(Request $request, $node) { @@ -297,7 +282,8 @@ class NodesController extends Controller * * @param Request $request * @param integer $node - * @return mixed + * @return \Illuminate\Http\Response + * @throws \Exception */ public function allocationSetAlias(Request $request, $node) { @@ -342,51 +328,48 @@ class NodesController extends Controller return redirect()->route('admin.nodes.view.allocation', $node); } - public function getAllocationsJson(Request $request, $id) + /** + * Deletes a node from the system. + * + * @param Request $request + * @param integer $id + * @return \Illuminate\Http\RedirectResponse + */ + public function delete(Request $request, $id) { - $allocations = Models\Allocation::select('ip')->where('node_id', $id)->groupBy('ip')->get(); + $repo = new NodeRepository; - return response()->json($allocations); - } - - public function deleteNode(Request $request, $id) - { try { - $repo = new NodeRepository; $repo->delete($id); Alert::success('Successfully deleted the requested node from the panel.')->flash(); return redirect()->route('admin.nodes'); - } catch (DisplayException $e) { - Alert::danger($e->getMessage())->flash(); - } catch (\Exception $e) { - Log::error($e); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); Alert::danger('An unhandled exception occured while attempting to delete this node. Please try again.')->flash(); } - return redirect()->route('admin.nodes.view', [ - 'id' => $id, - 'tab' => 'tab_delete', - ]); + return redirect()->route('admin.nodes.view', $id); } - public function getConfigurationToken(Request $request, $id) + /** + * Returns the configuration token to auto-deploy a node. + * + * @param Request $request + * @param integer $id + * @return \Illuminate\Http\JsonResponse + */ + public function setToken(Request $request, $id) { - // Check if Node exists. Will lead to 404 if not. - Models\Node::findOrFail($id); + $node = Models\Node::findOrFail($id); - // Create a token - $token = new Models\NodeConfigurationToken(); - $token->node = $id; - $token->token = str_random(32); - $token->expires_at = Carbon::now()->addMinutes(5); // Expire in 5 Minutes - $token->save(); + $t = Models\NodeConfigurationToken::create([ + 'node_id' => $id, + 'token' => str_random(32), + ]); - $token_response = [ - 'token' => $token->token, - 'expires_at' => $token->expires_at->toDateTimeString(), - ]; - - return response()->json($token_response, 200); + return response()->json(['token' => $t->token]); } } diff --git a/app/Http/Controllers/Remote/RemoteController.php b/app/Http/Controllers/Remote/RemoteController.php index 23ae805b6..2e8b782a1 100644 --- a/app/Http/Controllers/Remote/RemoteController.php +++ b/app/Http/Controllers/Remote/RemoteController.php @@ -105,27 +105,26 @@ class RemoteController extends Controller return response('', 201); } - public function getConfiguration(Request $request, $tokenString) + public function getConfiguration(Request $request, $token) { // Try to query the token and the node from the database try { - $token = Models\NodeConfigurationToken::where('token', $tokenString)->firstOrFail(); - $node = Models\Node::findOrFail($token->node); + $model = Models\NodeConfigurationToken::with('node')->where('token', $token)->firstOrFail(); } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { return response()->json(['error' => 'token_invalid'], 403); } // Check if token is expired - if ($token->expires_at->lt(Carbon::now())) { - $token->delete(); + if ($model->created_at->lt(Carbon::now())) { + $model->delete(); return response()->json(['error' => 'token_expired'], 403); } // Delete the token, it's one-time use - $token->delete(); + $model->delete(); // Manually as getConfigurationAsJson() returns it in correct format already - return response($node->getConfigurationAsJson())->header('Content-Type', 'text/json'); + return response($model->node->getConfigurationAsJson())->header('Content-Type', 'text/json'); } } diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index ae77928a0..ebfb29756 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -232,79 +232,62 @@ class AdminRoutes 'uses' => 'Admin\NodesController@postNew', ]); - $router->get('/view/{id}/do/index', [ + $router->get('/view/{id}', [ 'as' => 'admin.nodes.view', 'uses' => 'Admin\NodesController@viewIndex', ]); - $router->get('/view/{id}/do/settings', [ + $router->get('/view/{id}/settings', [ 'as' => 'admin.nodes.view.settings', 'uses' => 'Admin\NodesController@viewSettings', ]); - $router->get('/view/{id}/do/configuration', [ + $router->post('/view/{id}/settings', [ + 'uses' => 'Admin\NodesController@updateSettings', + ]); + + $router->get('/view/{id}/configuration', [ 'as' => 'admin.nodes.view.configuration', 'uses' => 'Admin\NodesController@viewConfiguration', ]); - $router->get('/view/{id}/do/allocation', [ + $router->get('/view/{id}/allocation', [ 'as' => 'admin.nodes.view.allocation', 'uses' => 'Admin\NodesController@viewAllocation', ]); - $router->post('/view/{id}/do/allocation', [ + $router->post('/view/{id}/allocation', [ 'uses' => 'Admin\NodesController@createAllocation', ]); - $router->get('/view/{id}/do/servers', [ + $router->get('/view/{id}/servers', [ 'as' => 'admin.nodes.view.servers', 'uses' => 'Admin\NodesController@viewServers', ]); - $router->get('/view/{id}/do/delete', [ + $router->delete('/view/{id}/delete', [ 'as' => 'admin.nodes.view.delete', - 'uses' => 'Admin\NodesController@viewDelete', + 'uses' => 'Admin\NodesController@delete', ]); - $router->delete('/view/{id}/do/allocation/remove/{allocation}', [ + $router->delete('/view/{id}/allocation/remove/{allocation}', [ 'as' => 'admin.nodes.view.allocation.removeSingle', 'uses' => 'Admin\NodesController@allocationRemoveSingle', ]); - $router->post('/view/{id}/do/allocation/remove', [ + $router->post('/view/{id}/allocation/remove', [ 'as' => 'admin.nodes.view.allocation.removeBlock', 'uses' => 'Admin\NodesController@allocationRemoveBlock', ]); - $router->post('/view/{id}/do/allocation/alias', [ + $router->post('/view/{id}/allocation/alias', [ 'as' => 'admin.nodes.view.allocation.setAlias', 'uses' => 'Admin\NodesController@allocationSetAlias', ]); - $router->get('/view/{id}/allocations.json', [ - 'as' => 'admin.nodes.view.allocations', - 'uses' => 'Admin\NodesController@getAllocationsJson', - ]); - - $router->post('/view/{id}/allocations', [ - 'as' => 'admin.nodes.post.allocations', - 'uses' => 'Admin\NodesController@postAllocations', - ]); - - // View Deploy - $router->get('/view/{id}/deploy', [ - 'as' => 'admin.nodes.deply', - 'uses' => 'Admin\NodesController@getScript', - ]); - - $router->delete('/view/{id}', [ - 'as' => 'admin.nodes.delete', - 'uses' => 'Admin\NodesController@deleteNode', - ]); - - $router->get('/{id}/configurationtoken', [ - 'as' => 'admin.nodes.configuration-token', - 'uses' => 'Admin\NodesController@getConfigurationToken', + $router->get('/view/{id}/settings/token', [ + 'as' => 'admin.nodes.view.configuration.token', + 'uses' => 'Admin\NodesController@setToken', ]); }); diff --git a/app/Models/NodeConfigurationToken.php b/app/Models/NodeConfigurationToken.php index dd029ec78..b09e096bd 100644 --- a/app/Models/NodeConfigurationToken.php +++ b/app/Models/NodeConfigurationToken.php @@ -48,4 +48,14 @@ class NodeConfigurationToken extends Model * @var array */ protected $dates = ['created_at', 'updated_at', 'expires_at']; + + /** + * Gets the node associated with a configuration token. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function node() + { + return $this->belongsTo(Node::class); + } } diff --git a/database/migrations/2017_03_03_224254_UpdateNodeConfigTokensColumns.php b/database/migrations/2017_03_03_224254_UpdateNodeConfigTokensColumns.php new file mode 100644 index 000000000..58dc78ba9 --- /dev/null +++ b/database/migrations/2017_03_03_224254_UpdateNodeConfigTokensColumns.php @@ -0,0 +1,42 @@ +dropForeign(['node']); + $table->dropColumn('expires_at'); + $table->renameColumn('node', 'node_id'); + + $table->foreign('node_id')->references('id')->on('nodes'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('node_configuration_tokens', function (Blueprint $table) { + $table->dropForeign(['node_id']); + $table->renameColumn('node_id', 'node'); + $table->timestamp('expires_at')->after('token'); + + $table->foreign('node')->references('id')->on('nodes'); + }); + } +} diff --git a/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php b/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php index 536b3e384..8193eaeb9 100644 --- a/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php +++ b/resources/themes/pterodactyl/admin/nodes/view/configuration.blade.php @@ -81,7 +81,7 @@ @parent -@endsection diff --git a/resources/views/admin/nodes/index.blade.php b/resources/views/admin/nodes/index.blade.php deleted file mode 100644 index de1687087..000000000 --- a/resources/views/admin/nodes/index.blade.php +++ /dev/null @@ -1,96 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Node List -@endsection - -@section('scripts') - @parent - {!! Theme::css('css/vendor/fontawesome/animation.min.css') !!} -@endsection - -@section('content') -
    - -

    All Nodes


    - - - - - - - - - - - - - - - @foreach ($nodes as $node) - - - - - - - - - - - @endforeach - -
    NameLocationSSL
    {{ $node->name }}{{ $node->location->short }}
    -
    -
    {!! $nodes->render() !!}
    -
    -
    - -@endsection diff --git a/resources/views/admin/nodes/new.blade.php b/resources/views/admin/nodes/new.blade.php deleted file mode 100644 index 37add9812..000000000 --- a/resources/views/admin/nodes/new.blade.php +++ /dev/null @@ -1,187 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Create Node -@endsection - -@section('content') -
    - -

    Create New Node


    -
    -
    -
    -
    - -
    - -

    Character limits: a-zA-Z0-9_.- and [Space] (min 1, max 100 characters).

    -
    -
    -
    - -
    - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    -
    - -
    - -
    -

    Please enter domain name (e.g node.example.com) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node. - Why? -

    -
    -
    - -
    -
    - -
    -
    - -
    -
    -

    You should always leave SSL enabled for nodes. Disabling SSL could allow a malicious user to intercept traffic between the panel and the daemon potentially exposing sensitive information.

    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - - MB -
    -
    -
    - -
    - - % -
    -
    -
    -
    -
    -

    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.

    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - - MB -
    -
    -
    - -
    - - % -
    -
    -
    -
    -
    -

    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.

    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - -
    -

    The location at which your server files will be stored. Most users do not need to change this.

    -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -

    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.

    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    - -@endsection diff --git a/resources/views/admin/nodes/remote/deploy.blade.php b/resources/views/admin/nodes/remote/deploy.blade.php deleted file mode 100644 index b7283fcfd..000000000 --- a/resources/views/admin/nodes/remote/deploy.blade.php +++ /dev/null @@ -1,292 +0,0 @@ -#!/bin/bash -#### - # Pterodactyl - Panel - # Copyright (c) 2015 - 2017 Dane Everitt - # - # Permission is hereby granted, free of charge, to any person obtaining a copy - # of this software and associated documentation files (the "Software"), to deal - # in the Software without restriction, including without limitation the rights - # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - # copies of the Software, and to permit persons to whom the Software is - # furnished to do so, subject to the following conditions: - # - # The above copyright notice and this permission notice shall be included in all - # copies or substantial portions of the Software. - # - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. -#### -set +e -export DEBIAN_FRONTEND=noninteractive - -INSTALL_DIR="/srv/daemon" -DATA_DIR="{{ $node->daemonBase }}" -CURRENT_SYSTEM_KERNEL="$(uname -r)" -DL_VERSION="0.0.1" - -command_exists() { - command -v "$@" > /dev/null 2>&1 -} - -error_message() { - echo -e "\e[1m\e[97m\e[41m$1\e[0m" - exit 1 -} - -warning_message() { - echo -e "\e[43m\e[30m$1\e[0m" -} - -success_message() { - echo -e "\e[32m$1\e[0m" -} - -running_command() { - echo -e " ;; \e[47m\e[30m$1\e[0m" -} - -for i in "$@" -do - case $i in - -d|--directory) - INSTALL_DIR="$2" - ;; - -a|--datadir) - DATA_DIR="$2" - ;; - -g|--git) - USE_GIT=true - ;; - -u|--unstable) - USE_UNSTABLE=true - USE_GIT=true - ;; - -v|--version) - DL_VERSION="$2" - ;; - -h|--help) - echo "./installer [opts]" - echo " -d | --directory The directory to install the daemon into. (default: /srv/daemon)" - echo " -a | --datadir The directory that daemon users will be stored in. (default: /srv/daemon-data)" - echo " -g | --git Use this flag to download the daemon using a git clone. (default: false)" - echo " -u | --unstable Install unstable version of the daemon, automatically uses --git flag. (default: false)" - echo " -v | --version The version of the daemon to download." - exit - ;; - esac -shift -done - -warning_message "This program will automatically configure your system to run the Pterodactyl Daemon." -warning_message " - Install Location: $INSTALL_DIR" -warning_message " - Data Location: $DATA_DIR" -warning_message "This script will continue in 10 seconds. Press CRTL+C to exit now." -sleep 10 - -# Super basic system detection -if command_exists apt-get; then - INSTALL_CMD="apt-get -y" -elif command_exists yum; then - INSTALL_CMD="yum -y" -else - error_message "No supported repository manager was found." -fi - -if ! command_exists curl; then - warning_message "No file retrieval method found, installing curl now..." - running_command "$INSTALL_CMD -y install curl" - $INSTALL_CMD -y install curl - if [ "$?" -ne "0" ]; then - error_message "Unable to install curl and no other method was found for retrieving files." - fi -fi - -# Determine if the kernel is high enough version. -if command_exists awk; then - PROCESSED_KERNEL_VERSION=$(awk -F. '{print $1$2}' <<< $CURRENT_SYSTEM_KERNEL) -elif command_exists cut; then - PROCESSED_KERNEL_VERSION=$(cut -d. -f1-2 --output-delimiter='' <<< $CURRENT_SYSTEM_KERNEL) -else - error_message "You seem to be missing some core tools that this script needs: awk (or) cut" -fi - -if [ "$PROCESSED_KERNEL_VERSION" -lt "310" ]; then - error_message "Your kernel version must be at least 3.10 or higher for the daemon to work. You are using $CURRENT_SYSTEM_KERNEL" -fi - -check_cgroups() { - # Check CGroups - CGROUP_DIRECTORY_LISTING="$(awk '/[, ](cpu|cpuacct|cpuset|devices|freezer|memory)[, ]/ && $3 == "cgroup" { print $2 }' /proc/mounts | head -n1)" - if [ ! -z $CGROUP_DIRECTORY_LISTING -a -d $CGROUP_DIRECTORY_LISTING ]; then - CGROUP_DIRECTORY="$(dirname $CGROUP_DIRECTORY_LISTING 2>&1)" - if [ -d "$CGROUP_DIRECTORY/cpu" -a -d "$CGROUP_DIRECTORY/cpuacct" -a -d "$CGROUP_DIRECTORY/cpuset" -a -d "$CGROUP_DIRECTORY/devices" -a -d "$CGROUP_DIRECTORY/freezer" -a -d "$CGROUP_DIRECTORY/memory" ]; then - success_message "cgroups enabled and are valid on this machine." - else - error_message "You appear to be missing some important cgroups on this machine." - fi - else - if [ ! -e "/proc/cgroups" ]; then - error_message "This kernel does not appear to support cgroups! Please see https://gist.github.com/DaneEveritt/0f071f481b4d3fa637d4 for more information." - elif [ ! -d "/sys/fs/cgroup" ]; then - error_message "This kernel does not appear to support cgroups! Please see https://gist.github.com/DaneEveritt/0f071f481b4d3fa637d4 for more information." - fi - - if [ ! -f "/tmp/mount_cgroup.sh" ]; then - # Try to enable cgroups - warning_message "Attempting to enable cgroups on this machine..." - running_command "curl -L https://raw.githubusercontent.com/tianon/cgroupfs-mount/master/cgroupfs-mount > /tmp/mount_cgroup.sh" - curl -L https://raw.githubusercontent.com/tianon/cgroupfs-mount/master/cgroupfs-mount > /tmp/mount_cgroup.sh - - running_command "chmod +x /tmp/mount_cgroup.sh" - chmod +x /tmp/mount_cgroup.sh - - running_command "bash /tmp/mount_cgroup.sh" - bash /tmp/mount_cgroup.sh - check_cgroups - else - rm -rf /tmp/mount_cgroup.sh > /dev/null 2>&1 - error_message "Failed to enable cgroups on this machine." - fi - fi -} - -# Check those groups. -check_cgroups - -# Lets install the dependencies. -$INSTALL_CMD install linux-image-extra-$CURRENT_SYSTEM_KERNEL -if [ "$?" -ne "0" ]; then - warning_message "You appear to have a non-generic kernel meaning we could not install extra kernel tools." - warning_message "We will continue to install, but some docker enhancements might not work as expected." - warning_message "Continuing in 10 seconds, press CTRL+C to cancel this script." - sleep 10 -fi - -success_message "Installing Docker..." -running_command "curl -L https://get.docker.com/ | sh" -curl -L https://get.docker.com/ | sh -if [ "$?" -ne "0" ]; then - error_message "Unable to install docker, an error occured!" -fi; - -success_message "Installing NodeJS 5.x..." -running_command "curl -L https://deb.nodesource.com/setup_5.x | sudo -E bash -" -curl -L https://deb.nodesource.com/setup_5.x | sudo -E bash - -if [ "$?" -ne "0" ]; then - error_message "Unable to configure NodeJS, an error occured!" -fi; - -running_command "$INSTALL_CMD install tar nodejs" -$INSTALL_CMD install tar nodejs -if [ "$?" -ne "0" ]; then - error_message "Unable to install NodeJS or Tar, an error occured!" -fi; - -running_command "mkdir -p $INSTALL_DIR $DATA_DIR" -mkdir -p $INSTALL_DIR $DATA_DIR -cd $INSTALL_DIR - -if [ -z $USE_UNSTABLE -a -z $USE_GIT ]; then - CLEANUP_PROGRAMS="nodejs docker-engine" - - running_command "curl -sI https://github.com/Pterodactyl/Daemon/archive/$DL_VERSION.tar.gz | head -n1 | cut -d$' ' -f2" - GITHUB_STATUS="$(curl -sI https://github.com/Pterodactyl/Daemon/archive/$DL_VERSION.tar.gz | head -n1 | cut -d$' ' -f2)" - if [ $GITHUB_STATUS -ne "200" ]; then - $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 - error_message "Github returned a non-200 response code ($GITHUB_STATUS)" - fi - - running_command "curl -L \"https://github.com/Pterodactyl/Daemon/archive/$DL_VERSION.tar.gz\" > daemon.tar.gz" - curl -L "https://github.com/Pterodactyl/Daemon/archive/$DL_VERSION.tar.gz" > daemon.tar.gz - - running_command "tar --strip-components=1 -xzvf daemon.tar.gz" - tar --strip-components=1 -xzvf daemon.tar.gz 2>&1 - if [ "$?" -ne "0" ]; then - $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 - cd ~ && rm -rf $INSTALL_DIR 2>&1 - error_message "Unable to install the daemon due to an error while attempting to unpack files." - fi -elif [ $USE_GIT ]; then - CLEANUP_PROGRAMS="nodejs docker-engine git" - running_command "$INSTALL_CMD install git" - $INSTALL_CMD install git - - running_command "git clone https://github.com/Pterodactyl/Daemon.git ." - git clone https://github.com/Pterodactyl/Daemon.git . - if [ -z $USE_UNSTABLE ]; then - running_command "git checkout tags/$DL_VERSION" - git checkout tags/$DL_VERSION - fi - if [ "$?" -ne "0" ]; then - $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 - cd ~ && rm -rf $INSTALL_DIR 2>&1 - error_message "Unable to install the daemon due to an error while attempting to clone files to the server." - fi -else - error_message "Could not match an install method!" -fi - -running_command "npm install --production" -npm install --production -if [ "$?" -ne "0" ]; then - $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 - cd ~ && rm -rf $INSTALL_DIR 2>&1 - error_message "Unable to install the daemon due to an error that occured while running npm install." -fi - -running_command "docker run -d --name ptdl-sftp -p 2022:22 -v $DATA_DIR:/sftp-root -v $INSTALL_DIR/config/credentials:/creds quay.io/pterodactyl/scrappy" -docker run -d --name ptdl-sftp -p 2022:22 -v $DATA_DIR:/sftp-root -v $INSTALL_DIR/config/credentials:/creds quay.io/pterodactyl/scrappy -if [ "$?" -ne "0" ]; then - $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 - cd ~ && rm -rf $INSTALL_DIR 2>&1 - error_message "Unable to install the daemon due to an error while creating a SFTP container." -fi - -echo '{ - "web": { - "listen": {{ $node->daemonListen }}, - "ssl": { - "enabled": {{ $node->sceheme === 'https' ? 'true' : 'false' }}, - "certificate": "/etc/letsencrypt/live/{{ $node->fqdn }}/fullchain.pem", - "key": "/etc/letsencrypt/live/{{ $node->fqdn }}/privkey.pem" - } - }, - "docker": { - "socket": "/var/run/docker.sock" - }, - "sftp": { - "path": "{{ $node->daemonBase }}", - "port": {{ $node->daemonSFTP }}, - "container": "ptdl-sftp" - }, - "logger": { - "path": "logs/", - "src": false, - "level": "info", - "period": "1d", - "count": 3 - }, - "remote": { - "download": "{{ route('remote.download') }}", - "installed": "{{ route('remote.install') }}" - }, - "uploads": { - "maximumSize": 100000000 - }, - "keys": [ - "{{ $node->daemonSecret }}" - ] -}' > config/core.json -if [ "$?" -ne "0" ]; then - $INSTALL_CMD remove $CLEANUP_PROGRAMS - cd ~ && rm -rf $INSTALL_DIR 2>&1 - error_message "An error occured while attempting to save the JSON file." -fi - -success_message "Congratulations, the daemon is now installed." -exit diff --git a/resources/views/admin/nodes/view.blade.php b/resources/views/admin/nodes/view.blade.php deleted file mode 100644 index 5a0879b72..000000000 --- a/resources/views/admin/nodes/view.blade.php +++ /dev/null @@ -1,814 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Managing Node: {{ $node->name }} -@endsection - -@section('scripts') - @parent - {!! Theme::js('js/vendor/socketio/socket.io.min.js') !!} - {!! Theme::js('js/bootstrap-notify.min.js') !!} - {!! Theme::js('js/vendor/chartjs/chart.min.js') !!} - {!! Theme::js('js/vendor/jquery/jquery-dateFormat.min.js') !!} - -@endsection - -@section('content') -
    - - -
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Daemon Version (Latest: {{ Version::getDaemon() }})
    System Information
    Total CPU Cores
    Total Servers{{ count($node->servers) }}
    Memory Allocated{{ is_numeric($stats->memory) ? $stats->memory : 0 }} MB of - @if(!is_null($node->memory_overallocate)) - {{ $node->memory }} - @else - {{ $node->memory }} - @endif - MB -
    Disk Allocated{{ is_numeric($stats->disk) ? $stats->disk : 0 }} MB of - @if(!is_null($node->disk_overallocate)) - {{ $node->disk }} - @else - {{ $node->disk }} - @endif - MB -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - Changing some details below may require that you change the configuration file on the node as well as restart the daemon. They have been marked with below. -
    -
    -
    - -
    - -

    Character limits: a-zA-Z0-9_.- and [Space] (min 1, max 100 characters).

    -
    -
    -
    - -
    - -
    -
    -
    - -
    - public) === '1') ? 'checked' : '' }} id="public_1" checked>
    - public) === '0') ? 'checked' : '' }} id="public_0"> -
    -
    -
    -
    -
    - -
    - -
    -

    Please enter domain name (e.g node.example.com) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node. - Why? -

    -
    -
    - -
    -
    - scheme) === 'https') ? 'checked' : '' }}/> -
    -
    - scheme) === 'http') ? 'checked' : '' }}/> -
    -
    -

    You should always leave SSL enabled for nodes. Disabling SSL could allow a malicious user to intercept traffic between the panel and the daemon potentially exposing sensitive information.

    -
    -
    -
    -
    -
    -
    -
    - -
    - - MB -
    -
    -
    - -
    - - % -
    -
    -
    - -
    - - MB -
    -
    -
    - -
    - - % -
    -
    -
    -
    -
    -

    Enter the total amount of disk space and memory avaliable for new servers. If you would like to allow overallocation of disk space or 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.

    -
    -
    -
    -
    -
    -
    -
    - -
    - - MB -
    -

    Enter the maximum size of files that can be uploaded through the web-based file manager.

    -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    -

    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.

    -
    -
    -
    -
    -
    -
    - -
    - Reset Daemon Master Key -
    -
    -
    -

    Resetting the daemon master key will void any request coming from the old key. This key is used for all sensitive operations on the daemon including server creation and deletion. We suggest changing this key regularly for security.

    -
    -
    -
    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    To simplify the configuration of nodes it is possible to fetch the config from the panel. A token is required for this process. The button below will generate a token and provide you with the commands necessary for automatic configuration of the node. Be aware that these tokens are only valid for 5 minutes.

    -
    -
    -

    -
    -
    -
    {{ $node->getConfigurationAsJson(true) }}
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Allocate Additional Ports

    -
    -
    -
    - - -
    -
    - -
    -
      -
    • - -
    • -
    -
    -

    You must enter a comma (,) or press the enter key after each port or range that you enter. They should appear in a blue box.

    - -
    -
    - - -
    -
    -
    -
    -
    - {!! csrf_field() !!} - - -
    -
    -
    -
    -
    -
    -
    - - - - - - - - - - @foreach($node->allocations as $allocation) - - - - - - - - @endforeach - -
    IP Address IP AliasPortAssigned To
    {{ $allocation->ip }} - - - {{ $allocation->port }} - @if(! is_null($allocation->server)) - {{ $allocation->server->name }} - @endif - - @if(is_null($allocation->server_id)) - - @else - - @endif -
    -
    - {{ $node->allocations->appends(['tab' => 'tab_allocation'])->render() }} -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - The data below is live output from the daemon. CPU usage is displayed relative to the assigned CPU allocation. For example, if a server is assigned 10% and the CPU usage below displays 90% that means the server is using 9% of the total system CPU. -
    - - - - - - - - - - - - - - @foreach($node->servers as $server) - - - - - - - - - - @endforeach - -
    NameOwnerServiceMemoryDiskCPUStatus
    {{ $server->name }}{{ $server->user->email }}{{ $server->service->name }}-- / {{ $server->memory === 0 ? '∞' : $server->memory }} MB{{ $server->disk }} MB-- %--
    -
    -
    -
    - @if(count($node->servers) === 0) -
    -
    -
    -
    -
    -
    -
    - {!! method_field('DELETE') !!} - {!! csrf_field() !!} - -
    -
    -
    -
    Deleting this node is a permanent action, it cannot be undone.
    -
    -
    -
    -
    -
    - @endif -
    -
    -
    -
    -
    - - -@endsection diff --git a/resources/views/admin/servers/index.blade.php b/resources/views/admin/servers/index.blade.php deleted file mode 100644 index e2e5010f5..000000000 --- a/resources/views/admin/servers/index.blade.php +++ /dev/null @@ -1,83 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Server List -@endsection - -@section('content') -
    - -

    All Servers


    -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - @foreach ($servers as $server) - suspended === 1 && !$server->trashed()) - class="warning" - @elseif($server->trashed()) - class="danger" - @endif - data-server="{{ $server->uuidShort }}"> - - - - - - @endforeach - -
    Server NameOwnerNode
    - {{ $server->name }} - @if($server->suspended === 1 && !$server->trashed()) - Suspended - @elseif($server->trashed()) - Pending Deletion - @endif - {{ $server->user->email }}{{ $server->node->name }}
    -
    -
    {!! $servers->render() !!}
    -
    -
    - -@endsection diff --git a/resources/views/admin/servers/new.blade.php b/resources/views/admin/servers/new.blade.php deleted file mode 100644 index dc1deef22..000000000 --- a/resources/views/admin/servers/new.blade.php +++ /dev/null @@ -1,511 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Create New Server -@endsection - -@section('scripts') - @parent - {!! Theme::js('js/vendor/typeahead/typeahead.min.js') !!} -@endsection - -@section('content') -
    - -

    Create New Server


    -
    -
    -
    -
    - -
    - -

    Character limits: a-z A-Z 0-9 _ - . and [Space] (max 200 characters).

    -
    -
    -
    - -
    - {{-- Hacky workaround to prevent Safari and Chrome from trying to suggest emails here --}} - - -
    -
    -
    -
    -
    -
    -
    - -
    - -
    - -

    The location in which this server will be deployed.

    -
    -
    - -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - - MB -
    -
    -
    - -
    - - MB -
    -
    -
    - -
    - - - - - Disable OOM Killer - -
    -
    -
    -
    -
    -

    If you do not want to assign swap space to a server simply put 0 for the value, or -1 to allow unlimited swap space. If you want to disable memory limiting on a server simply enter 0 into the memory field. We suggest leaving OOM Killer enabled unless you know what you are doing, disabling it could cause your server to hang unexpectedly.

    -

    -
    -
    -
    - -
    - - MB -
    -
    -
    - -
    - - % -
    -
    -
    - -
    - - I/O -
    -
    -
    -
    -
    -

    If you do not want to limit CPU usage set the value to 0. To determine a value, take the number physical cores and multiply it by 100. For example, on a quad core system (4 * 100 = 400) there is 400% available. To limit a server to using half of a single core, you would set the value to 50. To allow a server to use up to two physical cores, set the value to 200. BlockIO should be a value between 10 and 1000. Please see this documentation for more information about it.

    -

    -
    -
    -
    -
    -
    -
    - -
    - -
    - -

    Select the type of service that this server will be running.

    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    - -
    - - - - -
    -

    If you would like to use a custom docker image for this server please enter it here. Most users can ignore this option.

    -
    -
    -
    -
    -
    - -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    - -@endsection diff --git a/resources/views/admin/settings.blade.php b/resources/views/admin/settings.blade.php deleted file mode 100644 index 09e66d6fc..000000000 --- a/resources/views/admin/settings.blade.php +++ /dev/null @@ -1,97 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Administration -@endsection - -@section('content') -
    - -

    Panel Settings


    -
    -
    -
    - -
    - -

    This is the name that is used throughout the panel and in emails sent to clients.

    -
    -
    -
    - -
    - -

    This is the default language that all clients will use unless they manually change it.

    -
    -
    -
    -
    -
    -
    In order to modify your SMTP settings for sending mail you will need to edit the .env file in this project's root folder.
    -
    -
    -
    -
    - -
    - -

    The email address that panel emails will be sent from. Note that some SMTP services require this to match for a given API key.

    -
    -
    -
    - -
    - -

    The name that emails will appear to come from.

    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    - -@endsection diff --git a/resources/views/admin/users/index.blade.php b/resources/views/admin/users/index.blade.php deleted file mode 100644 index 7e85c8fe9..000000000 --- a/resources/views/admin/users/index.blade.php +++ /dev/null @@ -1,73 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} -{{-- Some Modifications (c) 2015 Dylan Seidt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Account List -@endsection - -@section('content') -
    - -

    All Registered Users


    -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - @foreach ($users as $user) - - - - - - - - @endforeach - -
    ID - Email - Client NameUsername
    #{{ $user->id }}{{ $user->email }}{{ $user->name_last }}, {{ $user->name_first }}{{ $user->username }}
    -
    -
    {!! $users->render() !!}
    -
    -
    - -@endsection diff --git a/resources/views/admin/users/new.blade.php b/resources/views/admin/users/new.blade.php deleted file mode 100644 index 8e0bf5f7a..000000000 --- a/resources/views/admin/users/new.blade.php +++ /dev/null @@ -1,132 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} -{{-- Some Modifications (c) 2015 Dylan Seidt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - New Account -@endsection - -@section('content') -
    - -

    Create New Account


    -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -

    Setting this to 'Yes' gives a user full administrative access.

    -
    -
    -
    -
    -
    -
    -
    -

    Providing a user password is optional. New user emails prompt users to create a password the first time they login. If a password is provided here you will need to find a different method of providing it to the user.

    -
    -
    -
    - -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - {!! csrf_field() !!} - - -
    -
    -
    -
    -
    - -@endsection diff --git a/resources/views/admin/users/view.blade.php b/resources/views/admin/users/view.blade.php deleted file mode 100644 index 3ba9ec035..000000000 --- a/resources/views/admin/users/view.blade.php +++ /dev/null @@ -1,171 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} -{{-- Some Modifications (c) 2015 Dylan Seidt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Viewing User -@endsection - -@section('content') -
    - -

    Viewing User: {{ $user->email }}

    -

    Registered {{ (new Carbon($user->created_at))->toRfc1123String() }}

    -
    -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    -
    -
    -
    - -
    - -

    Setting this to 'Yes' gives a user full administrative access.

    -
    -
    -
    -
    -
    -
    -
    -
    -

    Associated Servers


    - @if($user->servers) - - - - - - - - - - - - - @foreach($user->servers as $server) - - - - - - - - - @endforeach - -
    IdentifierServer NameNodeUsername
    {{ $server->uuidShort }}{{ $server->name }}{{ $server->node->name }}{{ $server->username }}@if($server->suspended === 0)Active@elseSuspended@endif
    - @else -
    There are no servers associated with this account.
    - @endif - -
    -
    -
    -
    -

    Delete Account


    -
    Warning! There most be no servers associated with this account in order for it to be deleted.
    -
    - {!! method_field('DELETE') !!} - {!! csrf_field() !!} - -
    -
    -
    -
    - -@endsection From e68846892023c20177a6a2d3992d5e394f545aaf Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 4 Mar 2017 19:03:49 -0500 Subject: [PATCH 25/35] Push updated server views --- CHANGELOG.md | 5 + .../Controllers/Admin/ServersController.php | 587 +++++++++++------- app/Http/Routes/AdminRoutes.php | 104 ++-- app/Jobs/DeleteServer.php | 2 +- app/Observers/ServerObserver.php | 34 +- app/Repositories/ServerRepository.php | 21 +- public/js/laroute.js | 2 +- public/themes/pterodactyl/css/pterodactyl.css | 4 +- .../themes/pterodactyl/js/admin/new-server.js | 2 +- .../pterodactyl/admin/servers/view.blade.php | 461 -------------- .../admin/servers/view/build.blade.php | 158 +++++ .../admin/servers/view/database.blade.php | 0 .../admin/servers/view/delete.blade.php | 141 +++++ .../admin/servers/view/details.blade.php | 170 +++++ .../admin/servers/view/index.blade.php | 203 ++++++ .../admin/servers/view/manage.blade.php | 127 ++++ .../admin/servers/view/startup.blade.php | 0 17 files changed, 1245 insertions(+), 776 deletions(-) delete mode 100644 resources/themes/pterodactyl/admin/servers/view.blade.php create mode 100644 resources/themes/pterodactyl/admin/servers/view/build.blade.php create mode 100644 resources/themes/pterodactyl/admin/servers/view/database.blade.php create mode 100644 resources/themes/pterodactyl/admin/servers/view/delete.blade.php create mode 100644 resources/themes/pterodactyl/admin/servers/view/details.blade.php create mode 100644 resources/themes/pterodactyl/admin/servers/view/index.blade.php create mode 100644 resources/themes/pterodactyl/admin/servers/view/manage.blade.php create mode 100644 resources/themes/pterodactyl/admin/servers/view/startup.blade.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 1829e20dd..a47cee758 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,17 @@ This project follows [Semantic Versioning](http://semver.org) guidelines. ### Changed * New theme applied to Admin CP. Many graphical changes were made, some data was moved around and some display data changed. Too much was changed to feasibly log it all in here. Major breaking changes or notable new features will be logged. * New server creation page now makes significantly less AJAX calls and is much quicker to respond. +* Server and Node view pages wee modified to split tabs into individual pages to make re-themeing and modifications significantly easier, and reduce MySQL query loads on page. + +### Fixed +* Fixes potential bug with invalid CIDR notation (ex: `192.168.1.1/z`) when adding allocations that could cause over 4 million records to be created at once. ### Added * Ability to assign multiple allocations at once when creating a new server. ### Deprecated * Old API calls to `Server::create` will fail due to changed data structure. +* Many old routes were modified to reflect new standards in panel, and many of the controller functions being called were also modified. This shouldn't really impact anyone unless you have been digging into the code and modifying things. ## v0.6.0-pre.4 (Courageous Carniadactylus) ### Fixed diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 0e217dcc7..000d5c830 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -29,6 +29,7 @@ use Alert; use Javascript; use Pterodactyl\Models; use Illuminate\Http\Request; +use GuzzleHttp\Exception\TransferException; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Repositories\ServerRepository; @@ -38,14 +39,12 @@ use Pterodactyl\Exceptions\DisplayValidationException; class ServersController extends Controller { /** - * Controller Constructor. + * Display the index page with all servers currently on the system. + * + * @param Request $request + * @return \Illuminate\View\View */ - public function __construct() - { - // - } - - public function getIndex(Request $request) + public function index(Request $request) { $servers = Models\Server::withTrashed()->with( 'node', 'user', 'allocation' @@ -60,7 +59,13 @@ class ServersController extends Controller ]); } - public function getNew(Request $request) + /** + * Display create new server page. + * + * @param Request $request + * @return \Illuminate\View\View + */ + public function new(Request $request) { $services = Models\Service::with('options.packs', 'options.variables')->get(); Javascript::put([ @@ -77,55 +82,38 @@ class ServersController extends Controller ]); } - public function getView(Request $request, $id) - { - $server = Models\Server::withTrashed()->with( - 'user', 'option.variables', 'variables', - 'node.allocations', 'databases.host' - )->findOrFail($id); - - $server->option->variables->transform(function ($item, $key) use ($server) { - $item->server_value = $server->variables->where('variable_id', $item->id)->pluck('variable_value')->first(); - - return $item; - }); - - return view('admin.servers.view', [ - 'server' => $server, - 'assigned' => $server->node->allocations->where('server_id', $server->id)->sortBy('port')->sortBy('ip'), - 'unassigned' => $server->node->allocations->where('server_id', null)->sortBy('port')->sortBy('ip'), - 'db_servers' => Models\DatabaseServer::all(), - ]); - } - - public function postNewServer(Request $request) + /** + * Create server controller method. + * + * @param Request $request + * @return \Illuminate\Response\RedirectResponse + */ + public function create(Request $request) { try { - $server = new ServerRepository; - $response = $server->create($request->except('_token')); + $repo = new ServerRepository; + $server = $repo->create($request->except('_token')); - return redirect()->route('admin.servers.view', ['id' => $response->id]); + return redirect()->route('admin.servers.view', $server->id); } catch (DisplayValidationException $ex) { return redirect()->route('admin.servers.new')->withErrors(json_decode($ex->getMessage()))->withInput(); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); - - return redirect()->route('admin.servers.new')->withInput(); } catch (\Exception $ex) { Log::error($ex); Alert::danger('An unhandled exception occured while attemping to add this server. Please try again.')->flash(); - - return redirect()->route('admin.servers.new')->withInput(); } + + return redirect()->route('admin.servers.new')->withInput(); } /** - * Returns a JSON tree of all avaliable nodes in a given location. + * Returns a tree of all avaliable nodes in a given location. * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Contracts\View\View + * @param Request $request + * @return array */ - public function postNewServerGetNodes(Request $request) + public function newServerNodes(Request $request) { $nodes = Models\Node::with('allocations')->where('location_id', $request->input('location'))->get(); @@ -149,263 +137,388 @@ class ServersController extends Controller })->values(); } - public function postUpdateServerDetails(Request $request, $id) + /** + * Display the index when viewing a specific server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewIndex(Request $request, $id) { + return view('admin.servers.view.index', ['server' => Models\Server::withTrashed()->findOrFail($id)]); + } + + /** + * Display the details page when viewing a specific server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewDetails(Request $request, $id) + { + $server = Models\Server::where('installed', 1)->findOrFail($id); + + return view('admin.servers.view.details', ['server' => $server]); + } + + /** + * Display the build details page when viewing a specific server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewBuild(Request $request, $id) + { + $server = Models\Server::where('installed', 1)->with('node.allocations')->findOrFail($id); + + return view('admin.servers.view.build', [ + 'server' => $server, + 'assigned' => $server->node->allocations->where('server_id', $server->id)->sortBy('port')->sortBy('ip'), + 'unassigned' => $server->node->allocations->where('server_id', null)->sortBy('port')->sortBy('ip'), + ]); + } + + /** + * Display startup configuration page for a server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewStartup(Request $request, $id) + { + $server = Models\Server::where('installed', 1)->with('option.variables', 'variables')->findOrFail($id); + $server->option->variables->transform(function ($item, $key) use ($server) { + $item->server_value = $server->variables->where('variable_id', $item->id)->pluck('variable_value')->first(); + + return $item; + }); + + return view('admin.servers.view.startup', ['server' => $server]); + } + + /** + * Display the database management page for a specific server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewDatabase(Request $request, $id) + { + $server = Models\Server::where('installed', 1)->with('databases.host')->findOrFail($id); + + return view('admin.servers.view.build', ['server' => $server]); + } + + /** + * Display the management page when viewing a specific server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewManage(Request $request, $id) + { + return view('admin.servers.view.manage', ['server' => Models\Server::findOrFail($id)]); + } + + /** + * Display the deletion page for a server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewDelete(Request $request, $id) + { + return view('admin.servers.view.delete', ['server' => Models\Server::withTrashed()->findOrFail($id)]); + } + + /** + * Update the details for a server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function setDetails(Request $request, $id) + { + $repo = new ServerRepository;; try { - $server = new ServerRepository; - $server->updateDetails($id, $request->intersect([ + $repo->updateDetails($id, $request->intersect([ 'owner_id', 'name', 'reset_token', ])); Alert::success('Server details were successfully updated.')->flash(); } catch (DisplayValidationException $ex) { - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_details', - ])->withErrors(json_decode($ex->getMessage()))->withInput(); + return redirect()->route('admin.servers.view.details', $id)->withErrors(json_decode($ex->getMessage()))->withInput(); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); } catch (\Exception $ex) { Log::error($ex); - Alert::danger('An unhandled exception occured while attemping to update this server. Please try again.')->flash(); + Alert::danger('An unhandled exception occured while attemping to update this server. This error has been logged.')->flash(); } - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_details', - ])->withInput(); + return redirect()->route('admin.servers.view.details', $id)->withInput(); } - public function postUpdateContainerDetails(Request $request, $id) + /** + * Set the new docker container for a server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function setContainer(Request $request, $id) { + $repo = new ServerRepository; + try { - $server = new ServerRepository; - $server->updateContainer($id, $request->intersect('docker_image')); + $repo->updateContainer($id, $request->intersect('docker_image')); + Alert::success('Successfully updated this server\'s docker image.')->flash(); } catch (DisplayValidationException $ex) { - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_details', - ])->withErrors(json_decode($ex->getMessage()))->withInput(); + return redirect()->route('admin.servers.view.details', $id)->withErrors(json_decode($ex->getMessage()))->withInput(); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); } catch (\Exception $ex) { Log::error($ex); - Alert::danger('An unhandled exception occured while attemping to update this server\'s docker image. Please try again.')->flash(); + Alert::danger('An unhandled exception occured while attemping to update this server\'s docker image. This error has been logged.')->flash(); } - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_details', - ]); + return redirect()->route('admin.servers.view.details', $id); } - public function postUpdateServerToggleBuild(Request $request, $id) + /** + * Toggles the install status for a server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function toggleInstall(Request $request, $id) + { + $repo = new ServerRepository; + try { + $repo->toggleInstall($id); + + Alert::success('Server install status was successfully toggled.')->flash(); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception occured while attemping to toggle this servers status. This error has been logged.')->flash(); + } + + return redirect()->route('admin.servers.view.manage', $id); + } + + /** + * Setup a server to have a container rebuild. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function rebuildContainer(Request $request, $id) { $server = Models\Server::with('node')->findOrFail($id); try { - $res = $server->node->guzzleClient([ + $server->node->guzzleClient([ 'X-Access-Server' => $server->uuid, 'X-Access-Token' => $server->node->daemonSecret, ])->request('POST', '/server/rebuild'); + Alert::success('A rebuild has been queued successfully. It will run the next time this server is booted.')->flash(); - } catch (\GuzzleHttp\Exception\TransferException $ex) { + } catch (TransferException $ex) { Log::warning($ex); - Alert::danger('An error occured while attempting to toggle a rebuild.')->flash(); + Alert::danger('A TransferException was encountered while trying to contact the daemon, please ensure it is online and accessible. This error has been logged.')->flash(); } - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_manage', - ]); + return redirect()->route('admin.servers.view.manage', $id); } - public function postUpdateServerUpdateBuild(Request $request, $id) + /** + * Manage the suspension status for a server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function manageSuspension(Request $request, $id) { + $repo = new ServerRepository; + $action = $request->input('action'); + + if (! in_array($action, ['suspend', 'unsuspend'])) { + Alert::danger('Invalid action was passed to function.')->flash(); + + return redirect()->route('admin.servers.view.manage', $id); + } + try { - $server = new ServerRepository; - $server->changeBuild($id, $request->intersect([ - 'allocation_id', 'add_allocations', - 'remove_allocations', 'memory', - 'swap', 'io', 'cpu', - ])); - Alert::success('Server details were successfully updated.')->flash(); - } catch (DisplayValidationException $ex) { - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_build', - ])->withErrors(json_decode($ex->getMessage()))->withInput(); + $repo->$action($id); + + Alert::success('Server has been ' . $action . 'ed.'); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); - - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_build', - ]); } catch (\Exception $ex) { Log::error($ex); - Alert::danger('An unhandled exception occured while attemping to add this server. Please try again.')->flash(); + Alert::danger('An unhandled exception occured while attemping to ' . $action . ' this server. This error has been logged.')->flash(); } - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_build', - ]); + return redirect()->route('admin.servers.view.manage', $id); } - public function deleteServer(Request $request, $id, $force = null) + /** + * Update the build configuration for a server. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function updateBuild(Request $request, $id) { + $repo = new ServerRepository; + try { - $server = new ServerRepository; - $server->deleteServer($id, $force); + $repo->changeBuild($id, $request->intersect([ + 'allocation_id', 'add_allocations', 'remove_allocations', + 'memory', 'swap', 'io', 'cpu', + ])); + + Alert::success('Server details were successfully updated.')->flash(); + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.servers.view.build', $id)->withErrors(json_decode($ex->getMessage()))->withInput(); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception occured while attemping to add this server. This error has been logged.')->flash(); + } + + return redirect()->route('admin.servers.view.build', $id); + } + + /** + * Start the server deletion process. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function delete(Request $request, $id) + { + $repo = new ServerRepository; + + try { + $repo->queueDeletion($id, ($request->input('is_force') > 0)); Alert::success('Server has been marked for deletion on the system.')->flash(); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception occured while attemping to delete this server. This error has been logged.')->flash(); + } + + return redirect()->route('admin.servers.view.delete', $id); + } + + /** + * Cancels a pending server deletion request. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function cancelDeletion(Request $request, $id) + { + $repo = new ServerRepository; + + $repo->cancelDeletion($id); + Alert::success('Server deletion has been cancelled. This server will remain suspended until you unsuspend it.')->flash(); + + return redirect()->route('admin.servers.view.delete', $id); + } + + /** + * Skips the queue and continues the server deletion process. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function continueDeletion(Request $request, $id, $method) + { + $repo = new ServerRepository; + + try { + $repo->delete($id, (isset($method) && $method === 'force')); + Alert::success('Server was successfully deleted from the system.')->flash(); return redirect()->route('admin.servers'); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); + } catch (TransferException $ex) { + Log::warning($ex); + Alert::danger('A TransferException occurred while attempting to delete this server from the daemon, please ensure it is running. This error has been logged.')->flash(); } catch (\Exception $ex) { Log::error($ex); - Alert::danger('An unhandled exception occured while attemping to delete this server. Please try again.')->flash(); + Alert::danger('An unhandled exception occured while attemping to delete this server. This error has been logged.')->flash(); } - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_delete', - ]); + return redirect()->route('admin.servers.view.delete', $id); } - public function postToggleInstall(Request $request, $id) - { - try { - $server = new ServerRepository; - $server->toggleInstall($id); - Alert::success('Server status was successfully toggled.')->flash(); - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An unhandled exception occured while attemping to toggle this servers status.')->flash(); - } finally { - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_manage', - ]); - } - } - - public function postUpdateServerStartup(Request $request, $id) - { - try { - $server = new ServerRepository; - $server->updateStartup($id, $request->except([ - '_token', - ]), true); - Alert::success('Server startup variables were successfully updated.')->flash(); - } catch (\Pterodactyl\Exceptions\DisplayException $e) { - Alert::danger($e->getMessage())->flash(); - } catch (\Exception $e) { - Log::error($e); - Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash(); - } finally { - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_startup', - ])->withInput(); - } - } - - public function postDatabase(Request $request, $id) - { - try { - $repo = new DatabaseRepository; - $repo->create($id, $request->only([ - 'db_server', 'database', 'remote', - ])); - Alert::success('Added new database to this server.')->flash(); - } catch (DisplayValidationException $ex) { - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_database', - ])->withInput()->withErrors(json_decode($ex->getMessage()))->withInput(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An exception occured while attempting to add a new database for this server.')->flash(); - } - - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_database', - ])->withInput(); - } - - public function postSuspendServer(Request $request, $id) - { - try { - $repo = new ServerRepository; - $repo->suspend($id); - Alert::success('Server has been suspended on the system. All running processes have been stopped and will not be startable until it is un-suspended.'); - } catch (DisplayException $e) { - Alert::danger($e->getMessage())->flash(); - } catch (\Exception $e) { - Log::error($e); - Alert::danger('An unhandled exception occured while attemping to suspend this server. Please try again.')->flash(); - } finally { - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_manage', - ]); - } - } - - public function postUnsuspendServer(Request $request, $id) - { - try { - $repo = new ServerRepository; - $repo->unsuspend($id); - Alert::success('Server has been unsuspended on the system. Access has been re-enabled.'); - } catch (DisplayException $e) { - Alert::danger($e->getMessage())->flash(); - } catch (\Exception $e) { - Log::error($e); - Alert::danger('An unhandled exception occured while attemping to unsuspend this server. Please try again.')->flash(); - } finally { - return redirect()->route('admin.servers.view', [ - 'id' => $id, - 'tab' => 'tab_manage', - ]); - } - } - - public function postQueuedDeletionHandler(Request $request, $id) - { - try { - $repo = new ServerRepository; - if (! is_null($request->input('cancel'))) { - $repo->cancelDeletion($id); - Alert::success('Server deletion has been cancelled. This server will remain suspended until you unsuspend it.')->flash(); - - return redirect()->route('admin.servers.view', $id); - } elseif (! is_null($request->input('delete'))) { - $repo->deleteNow($id); - Alert::success('Server was successfully deleted from the system.')->flash(); - - return redirect()->route('admin.servers'); - } elseif (! is_null($request->input('force_delete'))) { - $repo->deleteNow($id, true); - Alert::success('Server was successfully force deleted from the system.')->flash(); - - return redirect()->route('admin.servers'); - } - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - - return redirect()->route('admin.servers.view', $id); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An unhandled error occured while attempting to perform this action.')->flash(); - - return redirect()->route('admin.servers.view', $id); - } - } + // // + // public function postUpdateServerStartup(Request $request, $id) + // { + // try { + // $server = new ServerRepository; + // $server->updateStartup($id, $request->except([ + // '_token', + // ]), true); + // Alert::success('Server startup variables were successfully updated.')->flash(); + // } catch (\Pterodactyl\Exceptions\DisplayException $e) { + // Alert::danger($e->getMessage())->flash(); + // } catch (\Exception $e) { + // Log::error($e); + // Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash(); + // } finally { + // return redirect()->route('admin.servers.view', [ + // 'id' => $id, + // 'tab' => 'tab_startup', + // ])->withInput(); + // } + // } + // + // public function postDatabase(Request $request, $id) + // { + // try { + // $repo = new DatabaseRepository; + // $repo->create($id, $request->only([ + // 'db_server', 'database', 'remote', + // ])); + // Alert::success('Added new database to this server.')->flash(); + // } catch (DisplayValidationException $ex) { + // return redirect()->route('admin.servers.view', [ + // 'id' => $id, + // 'tab' => 'tab_database', + // ])->withInput()->withErrors(json_decode($ex->getMessage()))->withInput(); + // } catch (\Exception $ex) { + // Log::error($ex); + // Alert::danger('An exception occured while attempting to add a new database for this server.')->flash(); + // } + // + // return redirect()->route('admin.servers.view', [ + // 'id' => $id, + // 'tab' => 'tab_database', + // ])->withInput(); + // } + // // } diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index bf6b44bfa..6cdc18e4e 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -121,89 +121,103 @@ class AdminRoutes // View All Servers $router->get('/', [ 'as' => 'admin.servers', - 'uses' => 'Admin\ServersController@getIndex', ]); + 'uses' => 'Admin\ServersController@index', + ]); // View Create Server Page $router->get('/new', [ 'as' => 'admin.servers.new', - 'uses' => 'Admin\ServersController@getNew', + 'uses' => 'Admin\ServersController@new', ]); // Handle POST Request for Creating Server $router->post('/new', [ - 'uses' => 'Admin\ServersController@postNewServer', + 'uses' => 'Admin\ServersController@create', ]); // Assorted Page Helpers - $router->post('/new/get-nodes', [ - 'as' => 'admin.servers.new.get-nodes', - 'uses' => 'Admin\ServersController@postNewServerGetNodes', + $router->post('/new/nodes', [ + 'as' => 'admin.servers.new.nodes', + 'uses' => 'Admin\ServersController@newServerNodes', ]); - // View Specific Server $router->get('/view/{id}', [ 'as' => 'admin.servers.view', - 'uses' => 'Admin\ServersController@getView', + 'uses' => 'Admin\ServersController@viewIndex', ]); - // Database Stuffs - $router->post('/view/{id}/database', [ - 'as' => 'admin.servers.database', - 'uses' => 'Admin\ServersController@postDatabase', - ]); - - // Change Server Details - $router->post('/view/{id}/details', [ + $router->get('/view/{id}/details', [ 'as' => 'admin.servers.view.details', - 'uses' => 'Admin\ServersController@postUpdateServerDetails', + 'uses' => 'Admin\ServersController@viewDetails', ]); - // Change Server Details - $router->post('/view/{id}/container', [ - 'as' => 'admin.servers.post.container', - 'uses' => 'Admin\ServersController@postUpdateContainerDetails', + $router->post('/view/{id}/details', [ + 'uses' => 'Admin\ServersController@setDetails', ]); - // Change Server Details - $router->post('/view/{id}/startup', [ - 'as' => 'admin.servers.post.startup', - 'uses' => 'Admin\ServersController@postUpdateServerStartup', + $router->post('/view/{id}/details/container', [ + 'as' => 'admin.servers.view.details.container', + 'uses' => 'Admin\ServersController@setContainer', ]); - // Rebuild Server - $router->post('/view/{id}/rebuild', [ - 'uses' => 'Admin\ServersController@postUpdateServerToggleBuild', + $router->get('/view/{id}/build', [ + 'as' => 'admin.servers.view.build', + 'uses' => 'Admin\ServersController@viewBuild', ]); - // Change Build Details $router->post('/view/{id}/build', [ - 'uses' => 'Admin\ServersController@postUpdateServerUpdateBuild', + 'uses' => 'Admin\ServersController@updateBuild', ]); - // Suspend Server - $router->post('/view/{id}/suspend', [ - 'uses' => 'Admin\ServersController@postSuspendServer', + $router->get('/view/{id}/startup', [ + 'as' => 'admin.servers.view.startup', + 'uses' => 'Admin\ServersController@viewStartup', ]); - // Unsuspend Server - $router->post('/view/{id}/unsuspend', [ - 'uses' => 'Admin\ServersController@postUnsuspendServer', + $router->get('/view/{id}/database', [ + 'as' => 'admin.servers.view.database', + 'uses' => 'Admin\ServersController@viewDatabase', ]); - // Change Install Status - $router->post('/view/{id}/installed', [ - 'uses' => 'Admin\ServersController@postToggleInstall', + $router->get('/view/{id}/manage', [ + 'as' => 'admin.servers.view.manage', + 'uses' => 'Admin\ServersController@viewManage', ]); - // Delete [force delete] - $router->delete('/view/{id}/{force?}', [ - 'uses' => 'Admin\ServersController@deleteServer', + $router->post('/view/{id}/manage/toggle', [ + 'as' => 'admin.servers.view.manage.toggle', + 'uses' => 'Admin\ServersController@toggleInstall', ]); - $router->post('/view/{id}/queuedDeletion', [ - 'uses' => 'Admin\ServersController@postQueuedDeletionHandler', - 'as' => 'admin.servers.post.queuedDeletion', + $router->post('/view/{id}/manage/rebuild', [ + 'as' => 'admin.servers.view.manage.rebuild', + 'uses' => 'Admin\ServersController@rebuildContainer', ]); + + $router->post('/view/{id}/manage/suspension', [ + 'as' => 'admin.servers.view.manage.suspension', + 'uses' => 'Admin\ServersController@manageSuspension', + ]); + + $router->get('/view/{id}/delete', [ + 'as' => 'admin.servers.view.delete', + 'uses' => 'Admin\ServersController@viewDelete', + ]); + + $router->post('/view/{id}/delete', [ + 'uses' => 'Admin\ServersController@delete', + ]); + + $router->post('/view/{id}/delete/continue/{force?}', [ + 'as' => 'admin.servers.view.delete.continue', + 'uses' => 'Admin\ServersController@continueDeletion', + ]); + + $router->post('/view/{id}/delete/cancel', [ + 'as' => 'admin.servers.view.delete.cancel', + 'uses' => 'Admin\ServersController@cancelDeletion', + ]); + }); // Node Routes diff --git a/app/Jobs/DeleteServer.php b/app/Jobs/DeleteServer.php index a42637ff2..16d04b4ba 100644 --- a/app/Jobs/DeleteServer.php +++ b/app/Jobs/DeleteServer.php @@ -58,6 +58,6 @@ class DeleteServer extends Job implements ShouldQueue public function handle() { $repo = new ServerRepository; - $repo->deleteNow($this->id); + $repo->delete($this->id); } } diff --git a/app/Observers/ServerObserver.php b/app/Observers/ServerObserver.php index 5d919a559..5b746a7b6 100644 --- a/app/Observers/ServerObserver.php +++ b/app/Observers/ServerObserver.php @@ -41,8 +41,8 @@ class ServerObserver /** * Listen to the Server creating event. * - * @param Server $server [description] - * @return [type] [description] + * @param Server $server The server model. + * @return void */ public function creating(Server $server) { @@ -52,8 +52,8 @@ class ServerObserver /** * Listen to the Server created event. * - * @param Server $server [description] - * @return [type] [description] + * @param Server $server The server model. + * @return void */ public function created(Server $server) { @@ -73,8 +73,8 @@ class ServerObserver /** * Listen to the Server deleting event. * - * @param Server $server [description] - * @return [type] [description] + * @param Server $server The server model. + * @return void */ public function deleting(Server $server) { @@ -86,8 +86,8 @@ class ServerObserver /** * Listen to the Server deleted event. * - * @param Server $server [description] - * @return [type] [description] + * @param Server $server The server model. + * @return void */ public function deleted(Server $server) { @@ -103,8 +103,8 @@ class ServerObserver /** * Listen to the Server saving event. * - * @param Server $server [description] - * @return [type] [description] + * @param Server $server The server model. + * @return void */ public function saving(Server $server) { @@ -114,8 +114,8 @@ class ServerObserver /** * Listen to the Server saved event. * - * @param Server $server [description] - * @return [type] [description] + * @param Server $server The server model. + * @return void */ public function saved(Server $server) { @@ -123,10 +123,10 @@ class ServerObserver } /** - * Listen to the Server saving event. + * Listen to the Server updating event. * - * @param Server $server [description] - * @return [type] [description] + * @param Server $server The server model. + * @return void */ public function updating(Server $server) { @@ -136,8 +136,8 @@ class ServerObserver /** * Listen to the Server saved event. * - * @param Server $server [description] - * @return [type] [description] + * @param Server $server The server model. + * @return void */ public function updated(Server $server) { diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index 8d3bfa8dc..c8063b384 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -352,7 +352,7 @@ class ServerRepository // Validate Fields $validator = Validator::make($data, [ - 'owner_id' => 'sometimes|required|numeric|exists:users,id', + 'owner_id' => 'sometimes|required|integer|exists:users,id', 'name' => 'sometimes|required|regex:([\w .-]{1,200})', 'reset_token' => 'sometimes|required|accepted', ]); @@ -369,14 +369,14 @@ class ServerRepository $server = Models\Server::with('user')->findOrFail($id); // Update daemon secret if it was passed. - if (isset($data['reset_token']) || (isset($data['owner_id']) && $data['owner_id'] !== $server->user->id)) { + if (isset($data['reset_token']) || (isset($data['owner_id']) && (int) $data['owner_id'] !== $server->user->id)) { $oldDaemonKey = $server->daemonSecret; $server->daemonSecret = $uuid->generate('servers', 'daemonSecret'); $resetDaemonKey = true; } // Update Server Owner if it was passed. - if (isset($data['owner_id']) && $data['owner_id'] !== $server->user->id) { + if (isset($data['owner_id']) && (int) $data['owner_id'] !== $server->user->id) { $server->owner_id = $data['owner_id']; } @@ -463,7 +463,7 @@ class ServerRepository return true; } catch (TransferException $ex) { DB::rollBack(); - throw new DisplayException('An error occured while attempting to update the container image.', $ex); + throw new DisplayException('A TransferException occured while attempting to update the container image. Is the daemon online? This error has been logged.', $ex); } catch (\Exception $ex) { DB::rollBack(); throw $ex; @@ -590,7 +590,6 @@ class ServerRepository // This won't be committed unless the HTTP request succeedes anyways $server->save(); - dd($newBuild); if (! empty($newBuild)) { $server->node->guzzleClient([ 'X-Access-Server' => $server->uuid, @@ -607,7 +606,7 @@ class ServerRepository return $server; } catch (TransferException $ex) { DB::rollBack(); - throw new DisplayException('An error occured while attempting to update the configuration.', $ex); + throw new DisplayException('A TransferException occured while attempting to update the server configuration, check that the daemon is online. This error has been logged.', $ex); } catch (\Exception $ex) { DB::rollBack(); throw $ex; @@ -723,13 +722,13 @@ class ServerRepository } } - public function deleteServer($id, $force) + public function queueDeletion($id, $force = false) { $server = Models\Server::findOrFail($id); DB::beginTransaction(); try { - if ($force === 'force' || $force) { + if ($force) { $server->installed = 3; $server->save(); } @@ -743,7 +742,7 @@ class ServerRepository } } - public function deleteNow($id, $force = false) + public function delete($id, $force = false) { $server = Models\Server::withTrashed()->with('node')->findOrFail($id); @@ -819,8 +818,8 @@ class ServerRepository public function toggleInstall($id) { $server = Models\Server::findOrFail($id); - if ($server->installed === 2) { - throw new DisplayException('This server was marked as having a failed install, you cannot override this.'); + if ($server->installed > 1) { + throw new DisplayException('This server was marked as having a failed install or being deleted, you cannot override this.'); } $server->installed = ! $server->installed; diff --git a/public/js/laroute.js b/public/js/laroute.js index f074f2812..09ff8ad96 100644 --- a/public/js/laroute.js +++ b/public/js/laroute.js @@ -6,7 +6,7 @@ absolute: false, rootUrl: 'http://pterodactyl.app', - routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/get-nodes","name":"admin.servers.new.get-nodes","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postNewServerGetNodes"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postDatabase"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":"admin.servers.view.details","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/container","name":"admin.servers.post.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateContainerDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.post.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerStartup"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/rebuild","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerToggleBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUpdateServerUpdateBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/suspend","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postSuspendServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/unsuspend","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postUnsuspendServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/installed","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@postToggleInstall"},{"host":null,"methods":["DELETE"],"uri":"admin\/servers\/view\/{id}\/{force?}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@deleteServer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/queuedDeletion","name":"admin.servers.post.queuedDeletion","action":"Pterodactyl\Http\Controllers\Admin\ServersController@postQueuedDeletionHandler"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@new"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings","name":"admin.nodes.view.settings","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewSettings"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@updateSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/configuration","name":"admin.nodes.view.configuration","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":"admin.nodes.view.allocation","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewAllocation"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@createAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/servers","name":"admin.nodes.view.servers","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewServers"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/delete","name":"admin.nodes.view.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@delete"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove\/{allocation}","name":"admin.nodes.view.allocation.removeSingle","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove","name":"admin.nodes.view.allocation.removeBlock","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/alias","name":"admin.nodes.view.allocation.setAlias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationSetAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings\/token","name":"admin.nodes.view.configuration.token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}","name":"admin.services.service","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getService"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postService"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}\/configuration","name":"admin.services.service.config","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}\/configuration","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@newOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":"admin.services.option","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOption"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{service}\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":"admin.services.option.variable.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}","name":"admin.services.option.variable","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOptionVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}\/delete","name":"admin.services.option.variable.delete","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/new\/{option?}","name":"admin.services.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/upload\/{option?}","name":"admin.services.packs.uploadForm","action":"Pterodactyl\Http\Controllers\Admin\PackController@uploadForm"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/upload","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@postUpload"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs","name":"admin.services.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@listAll"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/option\/{option}","name":"admin.services.packs.option","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/service\/{service}","name":"admin.services.packs.service","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}","name":"admin.services.packs.edit","action":"Pterodactyl\Http\Controllers\Admin\PackController@edit"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/edit\/{pack}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}\/export\/{archive?}","name":"admin.services.packs.export","action":"Pterodactyl\Http\Controllers\Admin\PackController@export"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], + routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@new"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@create"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/nodes","name":"admin.servers.new.nodes","action":"Pterodactyl\Http\Controllers\Admin\ServersController@newServerNodes"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/details","name":"admin.servers.view.details","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@setDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details\/container","name":"admin.servers.view.details.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@setContainer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/build","name":"admin.servers.view.build","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@updateBuild"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.view.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.view.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDatabase"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/manage","name":"admin.servers.view.manage","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewManage"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/toggle","name":"admin.servers.view.manage.toggle","action":"Pterodactyl\Http\Controllers\Admin\ServersController@toggleInstall"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/rebuild","name":"admin.servers.view.manage.rebuild","action":"Pterodactyl\Http\Controllers\Admin\ServersController@rebuildContainer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/suspension","name":"admin.servers.view.manage.suspension","action":"Pterodactyl\Http\Controllers\Admin\ServersController@manageSuspension"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/delete","name":"admin.servers.view.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDelete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@delete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/continue\/{force?}","name":"admin.servers.view.delete.continue","action":"Pterodactyl\Http\Controllers\Admin\ServersController@continueDeletion"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/cancel","name":"admin.servers.view.delete.cancel","action":"Pterodactyl\Http\Controllers\Admin\ServersController@cancelDeletion"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@new"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings","name":"admin.nodes.view.settings","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewSettings"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@updateSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/configuration","name":"admin.nodes.view.configuration","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":"admin.nodes.view.allocation","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewAllocation"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@createAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/servers","name":"admin.nodes.view.servers","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewServers"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/delete","name":"admin.nodes.view.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@delete"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove\/{allocation}","name":"admin.nodes.view.allocation.removeSingle","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove","name":"admin.nodes.view.allocation.removeBlock","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/alias","name":"admin.nodes.view.allocation.setAlias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationSetAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings\/token","name":"admin.nodes.view.configuration.token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}","name":"admin.services.service","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getService"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postService"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}\/configuration","name":"admin.services.service.config","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}\/configuration","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@newOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":"admin.services.option","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOption"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{service}\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":"admin.services.option.variable.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}","name":"admin.services.option.variable","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOptionVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}\/delete","name":"admin.services.option.variable.delete","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/new\/{option?}","name":"admin.services.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/upload\/{option?}","name":"admin.services.packs.uploadForm","action":"Pterodactyl\Http\Controllers\Admin\PackController@uploadForm"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/upload","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@postUpload"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs","name":"admin.services.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@listAll"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/option\/{option}","name":"admin.services.packs.option","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/service\/{service}","name":"admin.services.packs.service","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}","name":"admin.services.packs.edit","action":"Pterodactyl\Http\Controllers\Admin\PackController@edit"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/edit\/{pack}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}\/export\/{archive?}","name":"admin.services.packs.export","action":"Pterodactyl\Http\Controllers\Admin\PackController@export"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], prefix: '', route : function (name, parameters, route) { diff --git a/public/themes/pterodactyl/css/pterodactyl.css b/public/themes/pterodactyl/css/pterodactyl.css index 07b16522b..c4b1cf256 100644 --- a/public/themes/pterodactyl/css/pterodactyl.css +++ b/public/themes/pterodactyl/css/pterodactyl.css @@ -141,8 +141,8 @@ li.select2-results__option--highlighted[aria-selected="false"] > .user-block > . color: #eee; } -.select2-container--default .select2-selection--multiple .select2-selection__choice { - margin: 2.5px; +.select2-selection.select2-selection--multiple { + min-height: 36px !important; } .select2-search--inline .select2-search__field:focus { diff --git a/public/themes/pterodactyl/js/admin/new-server.js b/public/themes/pterodactyl/js/admin/new-server.js index 2b6b1b8ba..3e82cb1ad 100644 --- a/public/themes/pterodactyl/js/admin/new-server.js +++ b/public/themes/pterodactyl/js/admin/new-server.js @@ -111,7 +111,7 @@ $('#pLocationId').on('change', function (event) { $.ajax({ method: 'POST', - url: Router.route('admin.servers.new.get-nodes'), + url: Router.route('admin.servers.new.nodes'), headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') }, data: { location: currentLocation }, }).done(function (data) { diff --git a/resources/themes/pterodactyl/admin/servers/view.blade.php b/resources/themes/pterodactyl/admin/servers/view.blade.php deleted file mode 100644 index 5818f9510..000000000 --- a/resources/themes/pterodactyl/admin/servers/view.blade.php +++ /dev/null @@ -1,461 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Manage Server: {{ $server->name }} -@endsection - -@section('content-header') -

    {{ $server->name }}{{ $server->uuid }}

    - -@endsection - -@section('content') - @if($server->suspended && ! $server->trashed()) -
    - This server is suspended and has no user access. Processes cannot be started and files cannot be modified. All API access is disabled unless using a master token. -
    - @elseif($server->trashed()) -
    - This server is marked for deletion {{ Carbon::parse($server->deleted_at)->addMinutes(env('APP_DELETE_MINUTES', 10))->diffForHumans() }}. If you want to cancel this action simply click the button below. -

    -
    - - - - {!! csrf_field() !!} -
    -
    - @endif - @if(! $server->installed) -
    - This server is still running through the install process and is not avaliable for use just yet. This message will disappear once this process is completed. -
    - @elseif($server->installed === 2) -
    - This server failed to install properly. You should delete it and try to create it again or check the daemon logs. -
    - @endif -
    -
    - -
    -
    -@endsection - -@section('footer-scripts') - @parent - -@endsection diff --git a/resources/themes/pterodactyl/admin/servers/view/build.blade.php b/resources/themes/pterodactyl/admin/servers/view/build.blade.php new file mode 100644 index 000000000..c01149d97 --- /dev/null +++ b/resources/themes/pterodactyl/admin/servers/view/build.blade.php @@ -0,0 +1,158 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Server — {{ $server->name }}: Build Details +@endsection + +@section('content-header') +

    {{ $server->name }}Control allocations and system resources for this server.

    + +@endsection + +@section('content') +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    System Resources

    +
    +
    +
    + +
    + + MB +
    +

    The maximum amount of memory allowed for this container. Setting this to 0 will allow unlimited memorry in a container.

    +
    +
    + +
    + + MB +
    +

    Setting this to 0 will disable swap space on this server. Setting to -1 will allow unlimited swap.

    +
    +
    + +
    + + % +
    +

    Each physical core on the system is considered to be 100%. Setting this value to 0 will allow a server to use CPU time without restrictions.

    +
    +
    + +
    + +
    +

    Changing this value can have negative effects on all containers on the system. We strongly recommend leaving this value as 500.

    +
    + +
    +
    +
    +
    +
    +
    +

    Allocation Management

    +
    +
    +
    + + +

    The default connection address that will be used for this game server.

    +
    +
    + +
    + +
    +

    Please note that due to software limitations you cannot assign identical ports on different IPs to the same server.

    +
    +
    + +
    + +
    +

    Simply select which ports you would like to remove from the list above. If you want to assign a port on a different IP that is already in use you can select it from the left and delete it here.

    +
    +
    + +
    +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/servers/view/database.blade.php b/resources/themes/pterodactyl/admin/servers/view/database.blade.php new file mode 100644 index 000000000..e69de29bb diff --git a/resources/themes/pterodactyl/admin/servers/view/delete.blade.php b/resources/themes/pterodactyl/admin/servers/view/delete.blade.php new file mode 100644 index 000000000..5a0cfe297 --- /dev/null +++ b/resources/themes/pterodactyl/admin/servers/view/delete.blade.php @@ -0,0 +1,141 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Server — {{ $server->name }}: Delete +@endsection + +@section('content-header') +

    {{ $server->name }}Delete this server from the panel.

    + +@endsection + +@section('content') +
    +
    + +
    +
    +
    + @if($server->trashed()) +
    +
    +
    +

    Marked for Deletion

    +
    +
    +

    This server is currently marked for deletion by the system {{ Carbon::parse($server->deleted_at)->addMinutes(env('APP_DELETE_MINUTES', 10))->diffForHumans() }}.

    +

    Deleting a server is an irreversible action. All server data (including files and users) will be removed from the system.

    +
    + +
    +
    + @endif +
    +
    +
    +

    Safely Delete Server

    +
    +
    +

    This action will attempt to delete the server from both the panel and daemon. If either one reports an error the action will be cancelled.

    +

    Deleting a server is an irreversible action. All server data (including files and users) will be removed from the system.

    +
    + +
    +
    +
    +
    +
    +

    Force Delete Server

    +
    +
    +

    This action will attempt to delete the server from both the panel and daemon. The the daemon does not respond, or reports an error the deletion will continue.

    +

    Deleting a server is an irreversible action. All server data (including files and users) will be removed from the system. This method may leave dangling files on your daemon if it reports an error.

    +
    + +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/servers/view/details.blade.php b/resources/themes/pterodactyl/admin/servers/view/details.blade.php new file mode 100644 index 000000000..618533ae3 --- /dev/null +++ b/resources/themes/pterodactyl/admin/servers/view/details.blade.php @@ -0,0 +1,170 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Server — {{ $server->name }}: Details +@endsection + +@section('content-header') +

    {{ $server->name }}Edit details for this server including owner and container.

    + +@endsection + +@section('content') +
    +
    + +
    +
    +
    +
    +
    +
    +

    Base Information

    +
    +
    +
    +
    + + +

    Character limits: a-zA-Z0-9_- and [Space] (max 35 characters).

    +
    +
    + + +

    You can change the owner of this server by changing this field to an email matching another use on this system. If you do this a new daemon security token will be generated automatically.

    +
    +
    + + +

    This token should not be shared with anyone as it has full control over this server.

    +
    +
    + +

    Resetting this token will cause any requests using the old token to fail.

    +
    +
    + +
    +
    +
    +
    +
    +
    +

    Container Setup

    +
    +
    +
    +
    + + +

    The docker image to use for this server. The default image for this service and option combination is {{ $server->option->docker_image }}.

    +
    +
    + +
    +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/servers/view/index.blade.php b/resources/themes/pterodactyl/admin/servers/view/index.blade.php new file mode 100644 index 000000000..f582e4572 --- /dev/null +++ b/resources/themes/pterodactyl/admin/servers/view/index.blade.php @@ -0,0 +1,203 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Server — {{ $server->name }} +@endsection + +@section('content-header') +

    {{ $server->name }}{{ $server->uuid }}

    + +@endsection + +@section('content') +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +

    Information

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    UUID{{ $server->uuid }}
    Docker Container ID
    Docker User ID
    Service{{ $server->option->service->name }} :: {{ $server->option->name }}
    Name{{ $server->name }}
    Memory{{ $server->memory }}MB / {{ $server->swap }}MB
    OOM Killer{!! ($server->oom_disabled === 0) ? 'Enabled' : 'Disabled' !!}
    Disk Space{{ $server->disk }}MB
    Block IO Weight{{ $server->io }}
    CPU Limit{{ $server->cpu }}%
    Default Connection{{ $server->allocation->ip }}:{{ $server->allocation->port }}
    Connection Alias + @if($server->allocation->alias !== $server->allocation->ip) + {{ $server->allocation->alias }}:{{ $server->allocation->port }} + @else + No Alias Assigned + @endif +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + @if($server->suspended) +
    +
    +
    +

    Suspended

    +
    +
    +
    + @endif + @if($server->installed !== 1) +
    +
    +
    +

    {{ (! $server->installed) ? 'Installing' : 'Install Failed' }}

    +
    +
    +
    + @endif +
    +
    +
    +

    {{ str_limit($server->user->username, 8) }}

    +

    Server Owner

    +
    +
    + + More info + +
    +
    +
    +
    +
    +

    {{ str_limit($server->node->name, 8) }}

    +

    Server Node

    +
    +
    + + More info + +
    +
    +
    +
    +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/servers/view/manage.blade.php b/resources/themes/pterodactyl/admin/servers/view/manage.blade.php new file mode 100644 index 000000000..4aee0000f --- /dev/null +++ b/resources/themes/pterodactyl/admin/servers/view/manage.blade.php @@ -0,0 +1,127 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Server — {{ $server->name }}: Manage +@endsection + +@section('content-header') +

    {{ $server->name }}Additional actions to control this server.

    + +@endsection + +@section('content') +
    +
    + +
    +
    +
    +
    +
    +
    +

    Install Status

    +
    +
    +

    If you need to change the install status from uninstalled to installed, or vice versa, you may do so with the button below.

    +
    + +
    +
    +
    +
    +
    +

    Rebuild Container

    +
    +
    +

    This will trigger a rebuild of the server container when it next starts up. This is useful if you modified the server configuration file manually, or something just didn't work out correctly.

    +
    + +
    +
    + @if(! $server->suspended) +
    +
    +
    +

    Suspend Server

    +
    +
    +

    This will suspend the server, stop any running processes, and immediately block the user from being able to access their files or otherwise manage the server through the panel or API.

    +
    + +
    +
    + @else +
    +
    +
    +

    Unsuspend Server

    +
    +
    +

    This will unsuspend the server and restore normal user access.

    +
    + +
    +
    + @endif +
    +@endsection diff --git a/resources/themes/pterodactyl/admin/servers/view/startup.blade.php b/resources/themes/pterodactyl/admin/servers/view/startup.blade.php new file mode 100644 index 000000000..e69de29bb From 5d59d364f82c879b129c07a4872cb2bc53eab053 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 4 Mar 2017 19:04:11 -0500 Subject: [PATCH 26/35] Fixes bug preventing proper updating of caches and models due to undefined Auth::user() --- CHANGELOG.md | 1 + app/Observers/ServerObserver.php | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a47cee758..919efdcb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines. ### Fixed * Fixes potential bug with invalid CIDR notation (ex: `192.168.1.1/z`) when adding allocations that could cause over 4 million records to be created at once. +* `[pre.4]` — Fixes bug preventing server updates from occurring by the system due to undefined `Auth::user()` in the event listener. ### Added * Ability to assign multiple allocations at once when creating a new server. diff --git a/app/Observers/ServerObserver.php b/app/Observers/ServerObserver.php index 5b746a7b6..973b276d2 100644 --- a/app/Observers/ServerObserver.php +++ b/app/Observers/ServerObserver.php @@ -142,8 +142,10 @@ class ServerObserver public function updated(Server $server) { // Clear Caches - Cache::forget('Server.byUuid.' . $server->uuid . Auth::user()->uuid); - Cache::forget('Server.byUuid.' . $server->uuidShort . Auth::user()->uuid); + if (Auth::user()) { + Cache::forget('Server.byUuid.' . $server->uuid . Auth::user()->uuid); + Cache::forget('Server.byUuid.' . $server->uuidShort . Auth::user()->uuid); + } event(new Events\Server\Updated($server)); } From cd0a45a7775e92d9603dbbf4f2fce6c4acb78cbf Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 4 Mar 2017 19:24:46 -0500 Subject: [PATCH 27/35] Fixes caching to actually clear the cache for *all* users, rather than the logged in user by using cache tags. --- CHANGELOG.md | 1 + app/Models/Server.php | 3 ++- app/Observers/ServerObserver.php | 15 +++++++++------ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 919efdcb8..bd7eee349 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines. ### Fixed * Fixes potential bug with invalid CIDR notation (ex: `192.168.1.1/z`) when adding allocations that could cause over 4 million records to be created at once. * `[pre.4]` — Fixes bug preventing server updates from occurring by the system due to undefined `Auth::user()` in the event listener. +* `[pre.4]` — Fixes `Server::byUuid()` caching to actually clear the cache for *all* users, rather than the logged in user by using cache tags. ### Added * Ability to assign multiple allocations at once when creating a new server. diff --git a/app/Models/Server.php b/app/Models/Server.php index 252646ba9..de85c45cc 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -26,6 +26,7 @@ namespace Pterodactyl\Models; use Auth; use Cache; +use Carbon; use Javascript; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; @@ -113,7 +114,7 @@ class Server extends Model public static function byUuid($uuid) { // Results are cached because we call this functions a few times on page load. - $result = Cache::remember('Server.byUuid.' . $uuid . Auth::user()->uuid, 60, function () use ($uuid) { + $result = Cache::tags(['Model:Server', 'Model:Server:byUuid:' . $uuid])->remember('Model:Server:byUuid:' . $uuid . Auth::user()->uuid, Carbon::now()->addMinutes(15), function () use ($uuid) { $query = self::with('service', 'node')->where(function ($q) use ($uuid) { $q->where('uuidShort', $uuid)->orWhere('uuid', $uuid); }); diff --git a/app/Observers/ServerObserver.php b/app/Observers/ServerObserver.php index 973b276d2..554e86a82 100644 --- a/app/Observers/ServerObserver.php +++ b/app/Observers/ServerObserver.php @@ -24,7 +24,6 @@ namespace Pterodactyl\Observers; -use Auth; use Cache; use Carbon; use Pterodactyl\Events; @@ -141,11 +140,15 @@ class ServerObserver */ public function updated(Server $server) { - // Clear Caches - if (Auth::user()) { - Cache::forget('Server.byUuid.' . $server->uuid . Auth::user()->uuid); - Cache::forget('Server.byUuid.' . $server->uuidShort . Auth::user()->uuid); - } + /** + * The cached byUuid model calls are tagged with Model:Server:byUuid: + * so that they can be accessed regardless of if there is an Auth::user() + * defined or not. + * + * We can also delete all cached byUuid items using the Model:Server tag. + */ + Cache::tags('Model:Server:byUuid:' . $server->uuid)->flush(); + Cache::tags('Model:Server:byUuid:' . $server->uuidShort)->flush(); event(new Events\Server\Updated($server)); } From cbbd3704fe459f0e475f304e5f0d64d076d7c955 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 4 Mar 2017 19:27:24 -0500 Subject: [PATCH 28/35] Add a second check here *just* to make sure someone doesn't break this. --- app/Models/Server.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Models/Server.php b/app/Models/Server.php index de85c45cc..524708cde 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -113,6 +113,10 @@ class Server extends Model */ public static function byUuid($uuid) { + if (! Auth::check()) { + throw new \Exception('You must call Server:byUuid as an authenticated user.'); + } + // Results are cached because we call this functions a few times on page load. $result = Cache::tags(['Model:Server', 'Model:Server:byUuid:' . $uuid])->remember('Model:Server:byUuid:' . $uuid . Auth::user()->uuid, Carbon::now()->addMinutes(15), function () use ($uuid) { $query = self::with('service', 'node')->where(function ($q) use ($uuid) { From d51ae5ec23be0036659436b090bee013d6dcd5d8 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 4 Mar 2017 19:28:23 -0500 Subject: [PATCH 29/35] Apply fixes from StyleCI (#332) --- app/Http/Controllers/Admin/ServersController.php | 2 +- app/Http/Routes/AdminRoutes.php | 1 - app/Observers/ServerObserver.php | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 000d5c830..c20a6de41 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -247,7 +247,7 @@ class ServersController extends Controller */ public function setDetails(Request $request, $id) { - $repo = new ServerRepository;; + $repo = new ServerRepository; try { $repo->updateDetails($id, $request->intersect([ 'owner_id', 'name', 'reset_token', diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index 6cdc18e4e..69e596a64 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -217,7 +217,6 @@ class AdminRoutes 'as' => 'admin.servers.view.delete.cancel', 'uses' => 'Admin\ServersController@cancelDeletion', ]); - }); // Node Routes diff --git a/app/Observers/ServerObserver.php b/app/Observers/ServerObserver.php index 554e86a82..92d1b8f9a 100644 --- a/app/Observers/ServerObserver.php +++ b/app/Observers/ServerObserver.php @@ -140,7 +140,7 @@ class ServerObserver */ public function updated(Server $server) { - /** + /* * The cached byUuid model calls are tagged with Model:Server:byUuid: * so that they can be accessed regardless of if there is an Auth::user() * defined or not. From 349b36d38a31510a258783e7d416b9dc9fe484ca Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 4 Mar 2017 23:45:22 -0500 Subject: [PATCH 30/35] Added startup management, cleaned up code. Refactored entire startup repository code block to be more efficient and cleaner. Also includes modifications to front-end to make it match backend name and design. --- .../Controllers/Admin/ServersController.php | 49 ++++---- .../Controllers/Server/ServerController.php | 4 +- app/Http/Routes/AdminRoutes.php | 4 + app/Repositories/ServerRepository.php | 116 +++++++----------- resources/lang/en/server.php | 2 + resources/lang/en/strings.php | 2 + .../admin/servers/view/startup.blade.php | 115 +++++++++++++++++ .../server/settings/startup.blade.php | 106 +++++++++------- 8 files changed, 252 insertions(+), 146 deletions(-) diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index c20a6de41..39e361dc3 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -475,27 +475,34 @@ class ServersController extends Controller return redirect()->route('admin.servers.view.delete', $id); } - // // - // public function postUpdateServerStartup(Request $request, $id) - // { - // try { - // $server = new ServerRepository; - // $server->updateStartup($id, $request->except([ - // '_token', - // ]), true); - // Alert::success('Server startup variables were successfully updated.')->flash(); - // } catch (\Pterodactyl\Exceptions\DisplayException $e) { - // Alert::danger($e->getMessage())->flash(); - // } catch (\Exception $e) { - // Log::error($e); - // Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash(); - // } finally { - // return redirect()->route('admin.servers.view', [ - // 'id' => $id, - // 'tab' => 'tab_startup', - // ])->withInput(); - // } - // } + /** + * Update the startup command as well as variables. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function saveStartup(Request $request, $id) + { + $repo = new ServerRepository; + + try { + $repo->updateStartup($id, $request->except('_token'), true); + + Alert::success('Startup variables were successfully modified and assigned for this server.')->flash(); + } catch(DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (TransferException $ex) { + Log::warning($ex); + Alert::danger('A TransferException occurred while attempting to update the startup for this server, please ensure the daemon is running. This error has been logged.')->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. This error has been logged.')->flash(); + } + + return redirect()->route('admin.servers.view.startup', $id); + } + // // public function postDatabase(Request $request, $id) // { diff --git a/app/Http/Controllers/Server/ServerController.php b/app/Http/Controllers/Server/ServerController.php index 07dee5439..7be93ff61 100644 --- a/app/Http/Controllers/Server/ServerController.php +++ b/app/Http/Controllers/Server/ServerController.php @@ -309,9 +309,7 @@ class ServerController extends Controller try { $repo = new ServerRepository; - $repo->updateStartup($server->id, $request->except([ - '_token', - ])); + $repo->updateStartup($server->id, $request->except('_token')); Alert::success('Server startup variables were successfully updated.')->flash(); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index 69e596a64..c40de6d18 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -174,6 +174,10 @@ class AdminRoutes 'uses' => 'Admin\ServersController@viewStartup', ]); + $router->post('/view/{id}/startup', [ + 'uses' => 'Admin\ServersController@saveStartup', + ]); + $router->get('/view/{id}/database', [ 'as' => 'admin.servers.view.database', 'uses' => 'Admin\ServersController@viewDatabase', diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index c8063b384..377450f66 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -617,87 +617,63 @@ class ServerRepository { $server = Models\Server::with('variables', 'option.variables')->findOrFail($id); - DB::beginTransaction(); - - try { - // Check the startup + DB::transaction(function () use ($admin, $data, $server) { if (isset($data['startup']) && $admin) { $server->startup = $data['startup']; $server->save(); } - // Check those Variables - $server->option->variables->transform(function ($item, $key) use ($server) { - $displayValue = $server->variables->where('variable_id', $item->id)->pluck('variable_value')->first(); - $item->server_value = (! is_null($displayValue)) ? $displayValue : $item->default_value; - - return $item; - }); - - $variableList = []; if ($server->option->variables) { - foreach ($server->option->variables as &$variable) { - // Move on if the new data wasn't even sent - if (! isset($data[$variable->env_variable])) { - $variableList[] = [ - 'id' => $variable->id, - 'env' => $variable->env_variable, - 'val' => $variable->server_value, - ]; + foreach($server->option->variables as &$variable) { + $set = isset($data['env_' . $variable->id]); + + // Variable is required but was not passed into the function. + if ($variable->required && ! $set) { + throw new DisplayException('A required variable (' . $variable->env_variable . ') was not passed in the request.'); + } + + // If user is not an admin and are trying to edit a non-editable field + // or an invisible field just silently skip the variable. + if (! $admin && (! $variable->user_editable || ! $variable->user_viewable)) { continue; } - // Update Empty but skip validation - if (empty($data[$variable->env_variable])) { - $variableList[] = [ - 'id' => $variable->id, - 'env' => $variable->env_variable, - 'val' => null, - ]; - continue; - } - - // Is the variable required? - // @TODO: is this even logical to perform this check? - if (isset($data[$variable->env_variable]) && empty($data[$variable->env_variable])) { - if ($variable->required) { - throw new DisplayException('A required service option variable field (' . $variable->env_variable . ') was included in this request but was left blank.'); + // Confirm value is valid when compared aganist regex. + // @TODO: switch to Laravel validation rules. + if ($set && ! is_null($variable->regex)) { + if (! preg_match($variable->regex, $data['env_' . $variable->id])) { + throw new DisplayException('The value passed for a variable (' . $variable->env_variable . ') could not be matched aganist the regex for that field (' . $variable->regex . ').'); } } - // Variable hidden and/or not user editable - if ((! $variable->user_viewable || ! $variable->user_editable) && ! $admin) { - throw new DisplayException('A service option variable field (' . $variable->env_variable . ') does not exist or you do not have permission to edit it.'); + $svar = Models\ServerVariable::firstOrNew([ + 'server_id' => $server->id, + 'variable_id' => $variable->id, + ]); + + // Set the value; if one was not passed set it to the default value + if ($set) { + $svar->variable_value = $data['env_' . $variable->id]; + + // Not passed, check if this record exists if so keep value, otherwise set default + } else { + $svar->variable_value = ($svar->exists) ? $svar->variable_value : $variable->default_value; } - // Check aganist Regex Pattern - if (! is_null($variable->regex) && ! preg_match($variable->regex, $data[$variable->env_variable])) { - throw new DisplayException('Failed to validate service option variable field (' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').'); - } - - $variableList[] = [ - 'id' => $variable->id, - 'env' => $variable->env_variable, - 'val' => $data[$variable->env_variable], - ]; + $svar->save(); } } - // Add Variables - $environmentVariables = [ - 'STARTUP' => $server->startup, - ]; - foreach ($variableList as $item) { - $environmentVariables[$item['env']] = $item['val']; + // Reload Variables + $server->load('variables'); + $environment = $server->option->variables->map(function ($item, $key) use ($server) { + $display = $server->variables->where('variable_id', $item->id)->pluck('variable_value')->first(); - // Update model or make a new record if it doesn't exist. - $model = Models\ServerVariable::firstOrNew([ - 'variable_id' => $item['id'], - 'server_id' => $server->id, - ]); - $model->variable_value = $item['val']; - $model->save(); - } + return [ + 'variable' => $item->env_variable, + 'value' => (! is_null($display)) ? $display : $item->default_value, + ]; + }); $server->node->guzzleClient([ 'X-Access-Server' => $server->uuid, @@ -705,21 +681,11 @@ class ServerRepository ])->request('PATCH', '/server', [ 'json' => [ 'build' => [ - 'env|overwrite' => $environmentVariables, + 'env|overwrite' => $environment->pluck('value', 'variable')->merge(['STARTUP' => $server->startup]), ], ], ]); - - DB::commit(); - - return true; - } catch (TransferException $ex) { - DB::rollBack(); - throw new DisplayException('An error occured while attempting to update the server configuration.', $ex); - } catch (\Exception $ex) { - DB::rollBack(); - throw $ex; - } + }); } public function queueDeletion($id, $force = false) diff --git a/resources/lang/en/server.php b/resources/lang/en/server.php index 0f77c1fe8..d8cae3ae2 100644 --- a/resources/lang/en/server.php +++ b/resources/lang/en/server.php @@ -233,6 +233,8 @@ return [ 'command' => 'Startup Command', 'edit_params' => 'Edit Parameters', 'update' => 'Update Startup Parameters', + 'startup_var' => 'Startup Command Variable', + 'startup_regex' => 'Verification Regex', ], 'sftp' => [ 'header' => 'SFTP Configuration', diff --git a/resources/lang/en/strings.php b/resources/lang/en/strings.php index ee2939f31..b3abb2bc1 100644 --- a/resources/lang/en/strings.php +++ b/resources/lang/en/strings.php @@ -63,4 +63,6 @@ return [ '2fa' => '2FA', 'logout' => 'Logout', 'admin_cp' => 'Admin Control Panel', + 'optional' => 'Optional', + 'read_only' => 'Read Only', ]; diff --git a/resources/themes/pterodactyl/admin/servers/view/startup.blade.php b/resources/themes/pterodactyl/admin/servers/view/startup.blade.php index e69de29bb..5e4175ad2 100644 --- a/resources/themes/pterodactyl/admin/servers/view/startup.blade.php +++ b/resources/themes/pterodactyl/admin/servers/view/startup.blade.php @@ -0,0 +1,115 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Server — {{ $server->name }}: Startup +@endsection + +@section('content-header') +

    {{ $server->name }}Control startup command as well as variables.

    + +@endsection + +@section('content') +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Startup Command Modification

    +
    +
    + +
    + {{ $server->option->display_executable }} + +
    +

    Edit your server's startup command here. The following variables are available by default: @{{SERVER_MEMORY}}, @{{SERVER_IP}}, and @{{SERVER_PORT}}.

    +
    + +
    +
    + @foreach($server->option->variables as $variable) +
    +
    +
    +

    {{ $variable->name }}

    +
    +
    + +

    {{ $variable->description }}

    +

    + @if($variable->required)Required@elseOptional@endif + @if($variable->user_viewable)Visible@elseHidden@endif + @if($variable->user_editable)Editable@elseLocked@endif +

    +
    + +
    +
    + @endforeach +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/server/settings/startup.blade.php b/resources/themes/pterodactyl/server/settings/startup.blade.php index 745d0d3fd..981d8e60c 100644 --- a/resources/themes/pterodactyl/server/settings/startup.blade.php +++ b/resources/themes/pterodactyl/server/settings/startup.blade.php @@ -35,64 +35,76 @@ @section('content')
    -
    -
    -
    -

    @lang('server.config.startup.command')

    -
    -
    -
    - {{ $service->executable }} - +
    +
    +
    +
    +

    @lang('server.config.startup.command')

    -
    -
    -
    -
    -
    -
    -

    @lang('server.config.startup.edit_params')

    -
    - @can('edit-startup', $server) - -
    - @foreach($variables as $item) -
    - -
    - user_editable === 1) - name="{{ $item->env_variable }}" - @else - readonly="readonly" - @endif - class="form-control" value="{{ old($item->env_variable, $item->a_serverValue) }}" data-action="matchRegex" data-regex="{{ $item->regex }}" /> -
    -

    {!! $item->description !!}

    -
    - @endforeach +
    +
    + {{ $service->executable }} +
    +
    + @can('edit-startup', $server) - - @else -
    -
    -

    @lang('auth.not_authorized')

    + @endcan +
    +
    + @can('edit-startup', $server) + @foreach($variables as $variable) +
    +
    +
    +

    {{ $variable->name }}

    +
    +
    + user_editable) + name="env_{{ $variable->id }}" + @else + readonly + @endif + class="form-control" type="text" value="{{ old('env_' . $variable->id, $variable->server_value) }}" /> +

    {{ $variable->description }}

    +

    + @if($variable->required && $variable->user_editable) + @lang('strings.required') + @elseif(! $variable->required && $variable->user_editable) + @lang('strings.optional') + @endif + @if(! $variable->user_editable) + @lang('strings.read_only') + @endif +

    +
    +
    - @endcan -
    -
    + @endforeach + @endcan +
    @endsection @section('footer-scripts') @parent {!! Theme::js('js/frontend/server.socket.js') !!} + @endsection From 5c32a912001f5b76b06a330b5dcdee88501cf849 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 5 Mar 2017 00:04:26 -0500 Subject: [PATCH 31/35] JS code updates --- public/js/laroute.js | 2 +- .../pterodactyl/js/frontend/serverlist.js | 25 ++++++------------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/public/js/laroute.js b/public/js/laroute.js index 09ff8ad96..eb550062a 100644 --- a/public/js/laroute.js +++ b/public/js/laroute.js @@ -6,7 +6,7 @@ absolute: false, rootUrl: 'http://pterodactyl.app', - routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@new"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@create"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/nodes","name":"admin.servers.new.nodes","action":"Pterodactyl\Http\Controllers\Admin\ServersController@newServerNodes"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/details","name":"admin.servers.view.details","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@setDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details\/container","name":"admin.servers.view.details.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@setContainer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/build","name":"admin.servers.view.build","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@updateBuild"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.view.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.view.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDatabase"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/manage","name":"admin.servers.view.manage","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewManage"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/toggle","name":"admin.servers.view.manage.toggle","action":"Pterodactyl\Http\Controllers\Admin\ServersController@toggleInstall"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/rebuild","name":"admin.servers.view.manage.rebuild","action":"Pterodactyl\Http\Controllers\Admin\ServersController@rebuildContainer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/suspension","name":"admin.servers.view.manage.suspension","action":"Pterodactyl\Http\Controllers\Admin\ServersController@manageSuspension"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/delete","name":"admin.servers.view.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDelete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@delete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/continue\/{force?}","name":"admin.servers.view.delete.continue","action":"Pterodactyl\Http\Controllers\Admin\ServersController@continueDeletion"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/cancel","name":"admin.servers.view.delete.cancel","action":"Pterodactyl\Http\Controllers\Admin\ServersController@cancelDeletion"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@new"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings","name":"admin.nodes.view.settings","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewSettings"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@updateSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/configuration","name":"admin.nodes.view.configuration","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":"admin.nodes.view.allocation","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewAllocation"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@createAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/servers","name":"admin.nodes.view.servers","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewServers"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/delete","name":"admin.nodes.view.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@delete"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove\/{allocation}","name":"admin.nodes.view.allocation.removeSingle","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove","name":"admin.nodes.view.allocation.removeBlock","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/alias","name":"admin.nodes.view.allocation.setAlias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationSetAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings\/token","name":"admin.nodes.view.configuration.token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}","name":"admin.services.service","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getService"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postService"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}\/configuration","name":"admin.services.service.config","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}\/configuration","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@newOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":"admin.services.option","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOption"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{service}\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":"admin.services.option.variable.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}","name":"admin.services.option.variable","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOptionVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}\/delete","name":"admin.services.option.variable.delete","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/new\/{option?}","name":"admin.services.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/upload\/{option?}","name":"admin.services.packs.uploadForm","action":"Pterodactyl\Http\Controllers\Admin\PackController@uploadForm"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/upload","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@postUpload"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs","name":"admin.services.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@listAll"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/option\/{option}","name":"admin.services.packs.option","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/service\/{service}","name":"admin.services.packs.service","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}","name":"admin.services.packs.edit","action":"Pterodactyl\Http\Controllers\Admin\PackController@edit"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/edit\/{pack}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}\/export\/{archive?}","name":"admin.services.packs.export","action":"Pterodactyl\Http\Controllers\Admin\PackController@export"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], + routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@new"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@create"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/nodes","name":"admin.servers.new.nodes","action":"Pterodactyl\Http\Controllers\Admin\ServersController@newServerNodes"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/details","name":"admin.servers.view.details","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@setDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details\/container","name":"admin.servers.view.details.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@setContainer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/build","name":"admin.servers.view.build","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@updateBuild"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.view.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewStartup"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@saveStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.view.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDatabase"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/manage","name":"admin.servers.view.manage","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewManage"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/toggle","name":"admin.servers.view.manage.toggle","action":"Pterodactyl\Http\Controllers\Admin\ServersController@toggleInstall"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/rebuild","name":"admin.servers.view.manage.rebuild","action":"Pterodactyl\Http\Controllers\Admin\ServersController@rebuildContainer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/suspension","name":"admin.servers.view.manage.suspension","action":"Pterodactyl\Http\Controllers\Admin\ServersController@manageSuspension"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/delete","name":"admin.servers.view.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDelete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@delete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/continue\/{force?}","name":"admin.servers.view.delete.continue","action":"Pterodactyl\Http\Controllers\Admin\ServersController@continueDeletion"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/cancel","name":"admin.servers.view.delete.cancel","action":"Pterodactyl\Http\Controllers\Admin\ServersController@cancelDeletion"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@new"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings","name":"admin.nodes.view.settings","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewSettings"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@updateSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/configuration","name":"admin.nodes.view.configuration","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":"admin.nodes.view.allocation","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewAllocation"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@createAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/servers","name":"admin.nodes.view.servers","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewServers"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/delete","name":"admin.nodes.view.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@delete"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove\/{allocation}","name":"admin.nodes.view.allocation.removeSingle","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove","name":"admin.nodes.view.allocation.removeBlock","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/alias","name":"admin.nodes.view.allocation.setAlias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationSetAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings\/token","name":"admin.nodes.view.configuration.token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}","name":"admin.services.service","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getService"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postService"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}\/configuration","name":"admin.services.service.config","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}\/configuration","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@newOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":"admin.services.option","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOption"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{service}\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":"admin.services.option.variable.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}","name":"admin.services.option.variable","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOptionVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}\/delete","name":"admin.services.option.variable.delete","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/new\/{option?}","name":"admin.services.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/upload\/{option?}","name":"admin.services.packs.uploadForm","action":"Pterodactyl\Http\Controllers\Admin\PackController@uploadForm"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/upload","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@postUpload"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs","name":"admin.services.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@listAll"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/option\/{option}","name":"admin.services.packs.option","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/service\/{service}","name":"admin.services.packs.service","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}","name":"admin.services.packs.edit","action":"Pterodactyl\Http\Controllers\Admin\PackController@edit"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/edit\/{pack}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}\/export\/{archive?}","name":"admin.services.packs.export","action":"Pterodactyl\Http\Controllers\Admin\PackController@export"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], prefix: '', route : function (name, parameters, route) { diff --git a/public/themes/pterodactyl/js/frontend/serverlist.js b/public/themes/pterodactyl/js/frontend/serverlist.js index 0490b7fbe..2a93a5a7c 100644 --- a/public/themes/pterodactyl/js/frontend/serverlist.js +++ b/public/themes/pterodactyl/js/frontend/serverlist.js @@ -17,16 +17,13 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. - -var ServerList = (function () { - +(function updateServerStatus() { var Status = { 0: 'Offline', 1: 'Online', 2: 'Starting', 3: 'Stopping' }; - $('.dynamic-update').each(function (index, data) { var element = $(this); var serverShortUUID = $(this).data('server'); @@ -81,20 +78,12 @@ var ServerList = (function () { element.find('[data-action="memory"]').html('--'); element.find('[data-action="cpu"]').html('--'); } - }).fail(function (jqXHR) { - console.error(jqXHR); - element.find('[data-action="status"]').html('Error'); - }); + } + }).fail(function (jqXHR) { + console.error(jqXHR); + element.find('[data-action="status"]').html('Error'); }); + }).promise().done(function () { setTimeout(updateServerStatus, 10000); - } - - return { - init: function () { - updateServerStatus(); - } - }; - + }); })(); - -ServerList.init(); From 16aaf531d6dcb58006303f047c979e44f9cccb51 Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Sun, 5 Mar 2017 17:25:28 +0100 Subject: [PATCH 32/35] switch user delete box to the style from nodes for consistency --- .../themes/pterodactyl/admin/users/view.blade.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/resources/themes/pterodactyl/admin/users/view.blade.php b/resources/themes/pterodactyl/admin/users/view.blade.php index 146a8c664..facddb1f5 100644 --- a/resources/themes/pterodactyl/admin/users/view.blade.php +++ b/resources/themes/pterodactyl/admin/users/view.blade.php @@ -149,12 +149,13 @@

    Delete User

    -
    Warning! There most be no servers associated with this account in order for it to be deleted.
    -

    -
    - {!! method_field('DELETE') !!} +

    There most be no servers associated with this account in order for it to be deleted.

    +
    +
    From 32dec97e4620cd7d17e85bd04c368a269d231090 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 5 Mar 2017 16:37:38 -0500 Subject: [PATCH 33/35] Improved database mechanics in admin CP for server view --- .../Controllers/Admin/ServersController.php | 99 ++++++--- app/Http/Routes/AdminRoutes.php | 13 ++ app/Repositories/DatabaseRepository.php | 160 +++++++-------- app/Repositories/ServerRepository.php | 10 +- public/js/laroute.js | 2 +- .../admin/servers/view/database.blade.php | 192 ++++++++++++++++++ 6 files changed, 357 insertions(+), 119 deletions(-) diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 39e361dc3..2efd1f876 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -211,7 +211,10 @@ class ServersController extends Controller { $server = Models\Server::where('installed', 1)->with('databases.host')->findOrFail($id); - return view('admin.servers.view.build', ['server' => $server]); + return view('admin.servers.view.database', [ + 'hosts' => Models\DatabaseServer::all(), + 'server' => $server + ]); } /** @@ -503,29 +506,73 @@ class ServersController extends Controller return redirect()->route('admin.servers.view.startup', $id); } - // - // public function postDatabase(Request $request, $id) - // { - // try { - // $repo = new DatabaseRepository; - // $repo->create($id, $request->only([ - // 'db_server', 'database', 'remote', - // ])); - // Alert::success('Added new database to this server.')->flash(); - // } catch (DisplayValidationException $ex) { - // return redirect()->route('admin.servers.view', [ - // 'id' => $id, - // 'tab' => 'tab_database', - // ])->withInput()->withErrors(json_decode($ex->getMessage()))->withInput(); - // } catch (\Exception $ex) { - // Log::error($ex); - // Alert::danger('An exception occured while attempting to add a new database for this server.')->flash(); - // } - // - // return redirect()->route('admin.servers.view', [ - // 'id' => $id, - // 'tab' => 'tab_database', - // ])->withInput(); - // } - // // + /** + * Creates a new database assigned to a specific server. + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function newDatabase(Request $request, $id) + { + $repo = new DatabaseRepository; + + try { + $repo->create($id, $request->only(['host', 'database', 'connection'])); + + Alert::success('A new database was assigned to this server successfully.')->flash(); + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.servers.view.database', $id)->withInput()->withErrors(json_decode($ex->getMessage()))->withInput(); + } catch(DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An exception occured while attempting to add a new database for this server. This error has been logged.')->flash(); + } + + return redirect()->route('admin.servers.view.database', $id)->withInput(); + } + + /** + * Resets the database password for a specific database on this server. + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function resetDatabasePassword(Request $request, $id) + { + $database = Models\Database::where('server_id', $id)->findOrFail($request->input('database')); + $repo = new DatabaseRepository; + + try { + $repo->password($database->id, str_random(20)); + + return response('', 204); + } catch (\Exception $ex) { + Log::error($ex); + + return response()->json(['error' => 'A unhandled exception occurred while attempting to reset this password. This error has been logged.'], 503); + } + } + + /** + * Deletes a database from a server. + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function deleteDatabase(Request $request, $id, $database) + { + $database = Models\Database::where('server_id', $id)->findOrFail($database); + $repo = new DatabaseRepository; + + try { + $repo->drop($database->id); + + return response('', 204); + } catch (\Exception $ex) { + Log::error($ex); + + return response()->json(['error' => 'A unhandled exception occurred while attempting to drop this database. This error has been logged.'], 503); + } + } } diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index c40de6d18..c25cb91e3 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -183,6 +183,19 @@ class AdminRoutes 'uses' => 'Admin\ServersController@viewDatabase', ]); + $router->post('/view/{id}/database', [ + 'uses' => 'Admin\ServersController@newDatabase', + ]); + + $router->patch('/view/{id}/database', [ + 'uses' => 'Admin\ServersController@resetDatabasePassword', + ]); + + $router->delete('/view/{id}/database/{database}/delete', [ + 'as' => 'admin.servers.view.database.delete', + 'uses' => 'Admin\ServersController@deleteDatabase', + ]); + $router->get('/view/{id}/manage', [ 'as' => 'admin.servers.view.manage', 'uses' => 'Admin\ServersController@viewManage', diff --git a/app/Repositories/DatabaseRepository.php b/app/Repositories/DatabaseRepository.php index c605a32de..4fd01c240 100644 --- a/app/Repositories/DatabaseRepository.php +++ b/app/Repositories/DatabaseRepository.php @@ -26,89 +26,98 @@ namespace Pterodactyl\Repositories; use DB; use Crypt; +use Config; use Validator; use Pterodactyl\Models; use Pterodactyl\Exceptions\DisplayException; -use Illuminate\Database\Capsule\Manager as Capsule; use Pterodactyl\Exceptions\DisplayValidationException; class DatabaseRepository { /** - * Adds a new database to a given database server. + * Adds a new database to a specified database host server. + * * @param int $server Id of the server to add a database for. * @param array $options Array of options for creating that database. + * + * @throws \Pterodactyl\Exceptions\DisplayException + * @throws \Pterodactyl\Exceptions\DisplayValidationException + * @throws \Exception * @return void */ - public function create($server, $options) + public function create($server, $data) { $server = Models\Server::findOrFail($server); - $validator = Validator::make($options, [ - 'db_server' => 'required|exists:database_servers,id', + + $validator = Validator::make($data, [ + 'host' => 'required|exists:database_servers,id', 'database' => 'required|regex:/^\w{1,100}$/', - 'remote' => 'required|regex:/^[0-9%.]{1,15}$/', + 'connection' => 'required|regex:/^[0-9%.]{1,15}$/', ]); if ($validator->fails()) { throw new DisplayValidationException($validator->errors()); } + $host = Models\DatabaseServer::findOrFail($data['host']); DB::beginTransaction(); + try { - $db = new Models\Database; - $db->fill([ + $database = Models\Database::firstOrNew([ 'server_id' => $server->id, - 'db_server' => $options['db_server'], - 'database' => "s{$server->id}_{$options['database']}", - 'username' => $server->uuidShort . '_' . str_random(7), - 'remote' => $options['remote'], - 'password' => Crypt::encrypt(str_random(20)), - ]); - $db->save(); - - // Contact Remote - $dbr = Models\DatabaseServer::findOrFail($options['db_server']); - - $capsule = new Capsule; - $capsule->addConnection([ - 'driver' => 'mysql', - 'host' => $dbr->host, - 'port' => $dbr->port, - 'database' => 'mysql', - 'username' => $dbr->username, - 'password' => Crypt::decrypt($dbr->password), - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => '', - 'options' => [ - \PDO::ATTR_TIMEOUT => 3, - ], + 'db_server' => $data['host'], + 'database' => sprintf('s%d_%s', $server->id, $data['database']), ]); - $capsule->setAsGlobal(); + if ($database->exists) { + throw new DisplayException('A database with those details already exists in the system.'); + } + + $database->username = sprintf('s%d_%s', $server->id, str_random(10)); + $database->remote = $data['connection']; + $database->password = Crypt::encrypt(str_random(20)); + + $database->save(); } catch (\Exception $ex) { DB::rollBack(); - throw new DisplayException('There was an error while connecting to the Database Host Server. Please check the error logs.', $ex); + throw $ex; } + Config::set('database.connections.dynamic', [ + 'driver' => 'mysql', + 'host' => $host->host, + 'port' => $host->port, + 'database' => 'mysql', + 'username' => $host->username, + 'password' => Crypt::decrypt($host->password), + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + ]); + try { - Capsule::statement('CREATE DATABASE `' . $db->database . '`'); - Capsule::statement('CREATE USER `' . $db->username . '`@`' . $db->remote . '` IDENTIFIED BY \'' . Crypt::decrypt($db->password) . '\''); - Capsule::statement('GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON `' . $db->database . '`.* TO `' . $db->username . '`@`' . $db->remote . '`'); - Capsule::statement('FLUSH PRIVILEGES'); + DB::connection('dynamic')->statement(sprintf('CREATE DATABASE IF NOT EXISTS `%s`', $database->database)); + DB::connection('dynamic')->statement(sprintf( + 'CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\'', + $database->username, $database->remote, Crypt::decrypt($database->password) + )); + DB::connection('dynamic')->statement(sprintf( + 'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON `%s`.* TO `%s`@`%s`', + $database->database, $database->username, $database->remote + )); + + DB::connection('dynamic')->statement('FLUSH PRIVILEGES'); + + // Save Everything DB::commit(); } catch (\Exception $ex) { try { - Capsule::statement('DROP DATABASE `' . $db->database . '`'); - Capsule::statement('DROP USER `' . $db->username . '`@`' . $db->remote . '`'); - } catch (\Exception $exi) { - // ignore it, if it fails its probably - // because we failed to ever make the DB - // or the user on the system. - } finally { - DB::rollBack(); - throw $ex; - } + DB::connection('dynamic')->statement(sprintf('DROP DATABASE IF EXISTS `%s`', $database->database)); + DB::connection('dynamic')->statement(sprintf('DROP USER IF EXISTS `%s`@`%s`', $database->username, $database->remote)); + DB::connection('dynamic')->statement('FLUSH PRIVILEGES'); + } catch (\Exception $ex) {} + + DB::rollBack(); + throw $ex; } } @@ -118,7 +127,7 @@ class DatabaseRepository * @param string $password The new password to use for the database. * @return bool */ - public function modifyPassword($id, $password) + public function password($id, $password) { $database = Models\Database::with('host')->findOrFail($id); @@ -127,33 +136,25 @@ class DatabaseRepository $database->password = Crypt::encrypt($password); $database->save(); - $capsule = new Capsule; - $capsule->addConnection([ + Config::set('database.connections.dynamic', [ 'driver' => 'mysql', 'host' => $database->host->host, 'port' => $database->host->port, 'database' => 'mysql', 'username' => $database->host->username, 'password' => Crypt::decrypt($database->host->password), - 'charset' => 'utf8', + 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', - 'prefix' => '', - 'options' => [ - \PDO::ATTR_TIMEOUT => 3, - ], ]); - $capsule->setAsGlobal(); - Capsule::statement(sprintf( + DB::connection('dynamic')->statement(sprintf( 'SET PASSWORD FOR `%s`@`%s` = PASSWORD(\'%s\')', - $database->username, - $database->remote, - $password + $database->username, $database->remote, $password )); DB::commit(); } catch (\Exception $ex) { - DB::rollback(); + DB::rollBack(); throw $ex; } } @@ -168,34 +169,25 @@ class DatabaseRepository $database = Models\Database::with('host')->findOrFail($id); DB::beginTransaction(); - try { - $capsule = new Capsule; - $capsule->addConnection([ + Config::set('database.connections.dynamic', [ 'driver' => 'mysql', 'host' => $database->host->host, 'port' => $database->host->port, 'database' => 'mysql', 'username' => $database->host->username, 'password' => Crypt::decrypt($database->host->password), - 'charset' => 'utf8', + 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', - 'prefix' => '', - 'options' => [ - \PDO::ATTR_TIMEOUT => 3, - ], ]); - $capsule->setAsGlobal(); - - Capsule::statement('DROP USER `' . $database->username . '`@`' . $database->remote . '`'); - Capsule::statement('DROP DATABASE `' . $database->database . '`'); + DB::connection('dynamic')->statement(sprintf('DROP DATABASE IF EXISTS `%s`', $database->database)); + DB::connection('dynamic')->statement(sprintf('DROP USER IF EXISTS `%s`@`%s`', $database->username, $database->remote)); + DB::connection('dynamic')->statement('FLUSH PRIVILEGES'); $database->delete(); DB::commit(); - - return true; } catch (\Exception $ex) { DB::rollback(); throw $ex; @@ -243,28 +235,20 @@ class DatabaseRepository } DB::beginTransaction(); - try { - $capsule = new Capsule; - $capsule->addConnection([ + Config::set('database.connections.dynamic', [ 'driver' => 'mysql', 'host' => $data['host'], 'port' => $data['port'], 'database' => 'mysql', 'username' => $data['username'], 'password' => $data['password'], - 'charset' => 'utf8', + 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', - 'prefix' => '', - 'options' => [ - \PDO::ATTR_TIMEOUT => 3, - ], ]); - $capsule->setAsGlobal(); - // Allows us to check that we can connect to things. - Capsule::select('SELECT 1 FROM dual'); + DB::connection('dynamic')->select('SELECT 1 FROM dual'); Models\DatabaseServer::create([ 'name' => $data['name'], diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index 377450f66..d911140a6 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -745,10 +745,12 @@ class ServerRepository // Delete Databases // This is the one un-recoverable point where // transactions will not save us. - $repository = new DatabaseRepository; - foreach (Models\Database::select('id')->where('server_id', $server->id)->get() as &$database) { - $repository->drop($database->id); - } + // + // @TODO: move to post-deletion event as a queued task! + // $repository = new DatabaseRepository; + // foreach (Models\Database::select('id')->where('server_id', $server->id)->get() as &$database) { + // $repository->drop($database->id); + // } $server->node->guzzleClient([ 'X-Access-Token' => $server->node->daemonSecret, diff --git a/public/js/laroute.js b/public/js/laroute.js index eb550062a..b4f553912 100644 --- a/public/js/laroute.js +++ b/public/js/laroute.js @@ -6,7 +6,7 @@ absolute: false, rootUrl: 'http://pterodactyl.app', - routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@new"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@create"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/nodes","name":"admin.servers.new.nodes","action":"Pterodactyl\Http\Controllers\Admin\ServersController@newServerNodes"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/details","name":"admin.servers.view.details","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@setDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details\/container","name":"admin.servers.view.details.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@setContainer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/build","name":"admin.servers.view.build","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@updateBuild"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.view.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewStartup"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@saveStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.view.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDatabase"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/manage","name":"admin.servers.view.manage","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewManage"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/toggle","name":"admin.servers.view.manage.toggle","action":"Pterodactyl\Http\Controllers\Admin\ServersController@toggleInstall"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/rebuild","name":"admin.servers.view.manage.rebuild","action":"Pterodactyl\Http\Controllers\Admin\ServersController@rebuildContainer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/suspension","name":"admin.servers.view.manage.suspension","action":"Pterodactyl\Http\Controllers\Admin\ServersController@manageSuspension"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/delete","name":"admin.servers.view.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDelete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@delete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/continue\/{force?}","name":"admin.servers.view.delete.continue","action":"Pterodactyl\Http\Controllers\Admin\ServersController@continueDeletion"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/cancel","name":"admin.servers.view.delete.cancel","action":"Pterodactyl\Http\Controllers\Admin\ServersController@cancelDeletion"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@new"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings","name":"admin.nodes.view.settings","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewSettings"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@updateSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/configuration","name":"admin.nodes.view.configuration","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":"admin.nodes.view.allocation","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewAllocation"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@createAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/servers","name":"admin.nodes.view.servers","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewServers"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/delete","name":"admin.nodes.view.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@delete"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove\/{allocation}","name":"admin.nodes.view.allocation.removeSingle","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove","name":"admin.nodes.view.allocation.removeBlock","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/alias","name":"admin.nodes.view.allocation.setAlias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationSetAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings\/token","name":"admin.nodes.view.configuration.token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}","name":"admin.services.service","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getService"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postService"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}\/configuration","name":"admin.services.service.config","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}\/configuration","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@newOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":"admin.services.option","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOption"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{service}\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":"admin.services.option.variable.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}","name":"admin.services.option.variable","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOptionVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}\/delete","name":"admin.services.option.variable.delete","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/new\/{option?}","name":"admin.services.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/upload\/{option?}","name":"admin.services.packs.uploadForm","action":"Pterodactyl\Http\Controllers\Admin\PackController@uploadForm"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/upload","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@postUpload"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs","name":"admin.services.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@listAll"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/option\/{option}","name":"admin.services.packs.option","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/service\/{service}","name":"admin.services.packs.service","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}","name":"admin.services.packs.edit","action":"Pterodactyl\Http\Controllers\Admin\PackController@edit"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/edit\/{pack}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}\/export\/{archive?}","name":"admin.services.packs.export","action":"Pterodactyl\Http\Controllers\Admin\PackController@export"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], + routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@new"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@create"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/nodes","name":"admin.servers.new.nodes","action":"Pterodactyl\Http\Controllers\Admin\ServersController@newServerNodes"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/details","name":"admin.servers.view.details","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@setDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details\/container","name":"admin.servers.view.details.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@setContainer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/build","name":"admin.servers.view.build","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@updateBuild"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.view.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewStartup"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@saveStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.view.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDatabase"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/database","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@newDatabase"},{"host":null,"methods":["PATCH"],"uri":"admin\/servers\/view\/{id}\/database","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@resetDatabasePassword"},{"host":null,"methods":["DELETE"],"uri":"admin\/servers\/view\/{id}\/database\/{database}\/delete","name":"admin.servers.view.database.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@deleteDatabase"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/manage","name":"admin.servers.view.manage","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewManage"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/toggle","name":"admin.servers.view.manage.toggle","action":"Pterodactyl\Http\Controllers\Admin\ServersController@toggleInstall"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/rebuild","name":"admin.servers.view.manage.rebuild","action":"Pterodactyl\Http\Controllers\Admin\ServersController@rebuildContainer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/suspension","name":"admin.servers.view.manage.suspension","action":"Pterodactyl\Http\Controllers\Admin\ServersController@manageSuspension"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/delete","name":"admin.servers.view.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDelete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@delete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/continue\/{force?}","name":"admin.servers.view.delete.continue","action":"Pterodactyl\Http\Controllers\Admin\ServersController@continueDeletion"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/cancel","name":"admin.servers.view.delete.cancel","action":"Pterodactyl\Http\Controllers\Admin\ServersController@cancelDeletion"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@new"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings","name":"admin.nodes.view.settings","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewSettings"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@updateSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/configuration","name":"admin.nodes.view.configuration","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":"admin.nodes.view.allocation","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewAllocation"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@createAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/servers","name":"admin.nodes.view.servers","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewServers"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/delete","name":"admin.nodes.view.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@delete"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove\/{allocation}","name":"admin.nodes.view.allocation.removeSingle","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove","name":"admin.nodes.view.allocation.removeBlock","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/alias","name":"admin.nodes.view.allocation.setAlias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationSetAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings\/token","name":"admin.nodes.view.configuration.token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}","name":"admin.services.service","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getService"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postService"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}\/configuration","name":"admin.services.service.config","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}\/configuration","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@newOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":"admin.services.option","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOption"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{service}\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":"admin.services.option.variable.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}","name":"admin.services.option.variable","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOptionVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}\/delete","name":"admin.services.option.variable.delete","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/new\/{option?}","name":"admin.services.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/upload\/{option?}","name":"admin.services.packs.uploadForm","action":"Pterodactyl\Http\Controllers\Admin\PackController@uploadForm"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/upload","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@postUpload"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs","name":"admin.services.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@listAll"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/option\/{option}","name":"admin.services.packs.option","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/service\/{service}","name":"admin.services.packs.service","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}","name":"admin.services.packs.edit","action":"Pterodactyl\Http\Controllers\Admin\PackController@edit"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/edit\/{pack}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}\/export\/{archive?}","name":"admin.services.packs.export","action":"Pterodactyl\Http\Controllers\Admin\PackController@export"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], prefix: '', route : function (name, parameters, route) { diff --git a/resources/themes/pterodactyl/admin/servers/view/database.blade.php b/resources/themes/pterodactyl/admin/servers/view/database.blade.php index e69de29bb..c9ebf506e 100644 --- a/resources/themes/pterodactyl/admin/servers/view/database.blade.php +++ b/resources/themes/pterodactyl/admin/servers/view/database.blade.php @@ -0,0 +1,192 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Server — {{ $server->name }}: Databases +@endsection + +@section('content-header') +

    {{ $server->name }}Manage server databases.

    + +@endsection + +@section('content') +
    +
    + +
    +
    +
    +
    +
    +
    +

    Active Databases

    +
    +
    + + + + + + + + + @foreach($server->databases as $database) + + + + + + + + @endforeach +
    DatabaseUsernameConnections FromHost
    {{ $database->database }}{{ $database->username }}{{ $database->remote }}{{ $database->host->host }}:{{ $database->host->port }} + + +
    +
    +
    +
    +
    +
    +
    +

    Create New Database

    +
    +
    +
    +
    + + +

    Select the host database server that this database should be created on.

    +
    +
    + +
    + s{{ $server->id }}_ + +
    +
    +
    + + +

    This should reflect the IP address that connections are allowed from. Uses standard MySQL notation. If unsure leave as %.

    +
    +
    + +
    +
    +
    +
    +@endsection + +@section('footer-scripts') + @parent + +@endsection From 33555547048ade331f44af1f128183951f1e9a82 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 5 Mar 2017 16:46:44 -0500 Subject: [PATCH 34/35] Fix frontend database password reset --- .../Controllers/Server/AjaxController.php | 15 +++++----- public/themes/pterodactyl/css/pterodactyl.css | 2 +- .../server/settings/databases.blade.php | 28 ++++++++++--------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/app/Http/Controllers/Server/AjaxController.php b/app/Http/Controllers/Server/AjaxController.php index 8f3736da7..4609ae270 100644 --- a/app/Http/Controllers/Server/AjaxController.php +++ b/app/Http/Controllers/Server/AjaxController.php @@ -224,17 +224,16 @@ class AjaxController extends Controller $server = Models\Server::byUuid($uuid); $this->authorize('reset-db-password', $server); - $database = Models\Database::where('id', $request->input('database'))->where('server_id', $server->id)->firstOrFail(); + $database = Models\Database::where('server_id', $server->id)->findOrFail($request->input('database')); + $repo = new Repositories\DatabaseRepository; + try { - $repo = new Repositories\DatabaseRepository; - $password = str_random(16); - $repo->modifyPassword($request->input('database'), $password); + $password = str_random(20); + $repo->password($database->id, $password); return response($password); - } catch (\Pterodactyl\Exceptions\DisplayException $ex) { - return response()->json([ - 'error' => $ex->getMessage(), - ], 503); + } catch (DisplayException $ex) { + return response()->json(['error' => $ex->getMessage()], 503); } catch (\Exception $ex) { Log::error($ex); diff --git a/public/themes/pterodactyl/css/pterodactyl.css b/public/themes/pterodactyl/css/pterodactyl.css index c4b1cf256..ca34e46a5 100644 --- a/public/themes/pterodactyl/css/pterodactyl.css +++ b/public/themes/pterodactyl/css/pterodactyl.css @@ -65,7 +65,7 @@ code { font-size: 14px !important; } -.middle { +.middle, .align-middle { vertical-align: middle !important; } diff --git a/resources/themes/pterodactyl/server/settings/databases.blade.php b/resources/themes/pterodactyl/server/settings/databases.blade.php index b69b0f36d..5e90be84f 100644 --- a/resources/themes/pterodactyl/server/settings/databases.blade.php +++ b/resources/themes/pterodactyl/server/settings/databases.blade.php @@ -49,17 +49,19 @@ @lang('strings.username') @lang('strings.password') @lang('server.config.database.host') + @can('reset-db-password', $server)@endcan @foreach($databases as $database) - {{ $database->database }} - {{ $database->username }} - {{ Crypt::decrypt($database->password) }} - @can('reset-db-password', $server) - - @endcan - - {{ $database->a_host }}:{{ $database->a_port }} + {{ $database->database }} + {{ $database->username }} + {{ Crypt::decrypt($database->password) }} + {{ $database->a_host }}:{{ $database->a_port }} + @can('reset-db-password', $server) + + + + @endcan @endforeach @@ -88,10 +90,10 @@ {!! Theme::js('js/frontend/server.socket.js') !!}