Skip to content

Commit 515e543

Browse files
committed
Add SFTP and Database management pages to new theme.
1 parent c7f3bb5 commit 515e543

File tree

11 files changed

+375
-23
lines changed

11 files changed

+375
-23
lines changed

app/Http/Controllers/Server/ServerController.php

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,8 @@ public function getIndex(Request $request)
6161
$node = Models\Node::find($server->node);
6262

6363
Javascript::put([
64-
'server' => [
65-
'uuid' => $server->uuid,
66-
'daemonSecret' => $server->daemonSecret,
67-
'username' => $server->username,
68-
],
69-
'node' => [
70-
'scheme' => $node->scheme,
71-
'fqdn' => $node->fqdn,
72-
'daemonListen' => $node->daemonListen,
73-
],
64+
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'daemonSecret', 'username']),
65+
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
7466
'meta' => [
7567
'saveFile' => route('server.files.save', $server->uuidShort),
7668
'csrfToken' => csrf_token(),
@@ -255,6 +247,45 @@ public function getSettings(Request $request, $uuid)
255247
]);
256248
}
257249

250+
public function getDatabases(Request $request, $uuid)
251+
{
252+
$server = Models\Server::getByUUID($uuid);
253+
$this->authorize('view-databases', $server);
254+
$node = Models\Node::find($server->node);
255+
256+
Javascript::put([
257+
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
258+
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
259+
]);
260+
261+
return view('server.settings.databases', [
262+
'server' => $server,
263+
'node' => $node,
264+
'databases' => Models\Database::select('databases.*', 'database_servers.host as a_host', 'database_servers.port as a_port')
265+
->where('server_id', $server->id)
266+
->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
267+
->get(),
268+
]);
269+
270+
}
271+
272+
public function getSFTP(Request $request, $uuid)
273+
{
274+
$server = Models\Server::getByUUID($uuid);
275+
$this->authorize('view-sftp', $server);
276+
$node = Models\Node::find($server->node);
277+
278+
Javascript::put([
279+
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'daemonSecret', 'username']),
280+
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
281+
]);
282+
283+
return view('server.settings.sftp', [
284+
'server' => $server,
285+
'node' => $node,
286+
]);
287+
}
288+
258289
public function postSettingsSFTP(Request $request, $uuid)
259290
{
260291
$server = Models\Server::getByUUID($uuid);
@@ -265,15 +296,15 @@ public function postSettingsSFTP(Request $request, $uuid)
265296
$repo->updateSFTPPassword($server->id, $request->input('sftp_pass'));
266297
Alert::success('Successfully updated this servers SFTP password.')->flash();
267298
} catch (DisplayValidationException $ex) {
268-
return redirect()->route('server.settings', $uuid)->withErrors(json_decode($ex->getMessage()));
299+
return redirect()->route('server.settings.sftp', $uuid)->withErrors(json_decode($ex->getMessage()));
269300
} catch (DisplayException $ex) {
270301
Alert::danger($ex->getMessage())->flash();
271302
} catch (\Exception $ex) {
272303
Log::error($ex);
273304
Alert::danger('An unknown error occured while attempting to update this server\'s SFTP settings.')->flash();
274305
}
275306

276-
return redirect()->route('server.settings', $uuid);
307+
return redirect()->route('server.settings.sftp', $uuid);
277308
}
278309

279310
public function postSettingsStartup(Request $request, $uuid)

app/Http/Routes/ServerRoutes.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,17 @@ public function map(Router $router)
5151
'uses' => 'Server\ServerController@getSettings',
5252
]);
5353

54-
$router->post('/settings/sftp', [
54+
$router->get('/settings/databases', [
55+
'as' => 'server.settings.databases',
56+
'uses' => 'Server\ServerController@getDatabases',
57+
]);
58+
59+
$router->get('/settings/sftp', [
5560
'as' => 'server.settings.sftp',
61+
'uses' => 'Server\ServerController@getSFTP',
62+
]);
63+
64+
$router->post('/settings/sftp', [
5665
'uses' => 'Server\ServerController@postSettingsSFTP',
5766
]);
5867

public/js/laroute.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/themes/pterodactyl/css/pterodactyl.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,15 @@
4545
code {
4646
font-size: 85%;
4747
}
48+
49+
.control-sidebar-dark .control-sidebar-menu > li > a.active {
50+
background: #1e282c;
51+
}
52+
53+
.callout-nomargin {
54+
margin: 0;
55+
}
56+
57+
.table {
58+
font-size: 14px !important;
59+
}

public/themes/pterodactyl/vendor/sweetalert/sweetalert.min.css

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/themes/pterodactyl/vendor/sweetalert/sweetalert.min.js

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/lang/en/strings.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@
2424
'2fa_token' => 'Authentication Token',
2525
'submit' => 'Submit',
2626
'close' => 'Close',
27+
'settings' => 'Settings',
28+
'configuration' => 'Configuration',
29+
'sftp' => 'SFTP',
30+
'databases' => 'Databases',
2731
];

resources/themes/pterodactyl/layouts/master.blade.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
{!! Theme::css('vendor/bootstrap/bootstrap.min.css') !!}
3030
{!! Theme::css('vendor/adminlte/admin.min.css') !!}
3131
{!! Theme::css('vendor/adminlte/colors/skin-blue.min.css') !!}
32+
{!! Theme::css('vendor/sweetalert/sweetalert.min.css') !!}
3233
{!! Theme::css('css/pterodactyl.css') !!}
3334
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
3435
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
@@ -161,7 +162,11 @@
161162
</span>
162163
</a>
163164
</li>
164-
<li class="treeview">
165+
<li class="treeview
166+
@if(in_array(Route::currentRouteName(), ['server.settings.sftp', 'server.settings.databases']))
167+
active
168+
@endif
169+
">
165170
<a href="#">
166171
<i class="fa fa-gears"></i>
167172
<span>Configuration</span>
@@ -170,9 +175,10 @@
170175
</span>
171176
</a>
172177
<ul class="treeview-menu">
173-
<li><a href="{{ route('server.settings', $server->uuidShort) }}"><i class="fa fa-angle-right"></i> SFTP Settings</a></li>
178+
<li><a href=""><i class="fa fa-angle-right"></i> Port Allocations</a></li>
179+
<li class="{{ Route::currentRouteName() !== 'server.settings.sftp' ?: 'active' }}"><a href="{{ route('server.settings.sftp', $server->uuidShort) }}"><i class="fa fa-angle-right"></i> SFTP Settings</a></li>
174180
<li><a href=""><i class="fa fa-angle-right"></i> Startup Parameters</a></li>
175-
<li><a href=""><i class="fa fa-angle-right"></i> Databases</a></li>
181+
<li class="{{ Route::currentRouteName() !== 'server.settings.databases' ?: 'active' }}"><a href="{{ route('server.settings.databases', $server->uuidShort) }}"><i class="fa fa-angle-right"></i> Databases</a></li>
176182
</ul>
177183
</li>
178184
@endif
@@ -223,15 +229,21 @@
223229
<ul class="control-sidebar-menu">
224230
@foreach (Pterodactyl\Models\Server::getUserServers() as $s)
225231
<li>
226-
<a href="{{ route('server.index', $s->uuidShort) }}">
232+
<a
233+
@if(isset($server) && isset($node))
234+
@if($server->uuidShort === $s->uuidShort)
235+
class="active"
236+
@endif
237+
@endif
238+
href="{{ route('server.index', $s->uuidShort) }}">
227239
@if($s->owner === Auth::user()->id)
228240
<i class="menu-icon fa fa-user bg-blue"></i>
229241
@else
230242
<i class="menu-icon fa fa-user-o bg-gray"></i>
231243
@endif
232244
<div class="menu-info">
233245
<h4 class="control-sidebar-subheading">{{ $s->name }}</h4>
234-
<p>{{ $s->uuidShort }}</p>
246+
<p>{{ $s->username }}</p>
235247
</div>
236248
</a>
237249
</li>
@@ -245,6 +257,7 @@
245257
@section('footer-scripts')
246258
{!! Theme::js('js/laroute.js') !!}
247259
{!! Theme::js('js/vendor/jquery/jquery.min.js') !!}
260+
{!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!}
248261
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
249262
{!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!}
250263
{!! Theme::js('vendor/adminlte/app.min.js') !!}

resources/themes/pterodactyl/server/index.blade.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@
4444
<div id="terminal" style="width:100%;"></div>
4545
</div>
4646
<div class="box-footer text-center">
47-
<button class="btn btn-success" data-attr="power" data-action="start">Start</button>
48-
<button class="btn btn-primary" data-attr="power" data-action="restart">Restart</button>
49-
<button class="btn btn-danger" data-attr="power" data-action="stop">Stop</button>
50-
<button class="btn btn-danger" data-attr="power" data-action="kill">Kill</button>
47+
@can('power-start', $server)<button class="btn btn-success" data-attr="power" data-action="start">Start</button>@endcan
48+
@can('power-off', $server)<button class="btn btn-primary" data-attr="power" data-action="restart">Restart</button>@endcan
49+
@can('power-restart', $server)<button class="btn btn-danger" data-attr="power" data-action="stop">Stop</button>@endcan
50+
@can('power-kill', $server)<button class="btn btn-danger" data-attr="power" data-action="kill">Kill</button>@endcan
5151
</div>
5252
</div>
5353
</div>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
{{-- Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> --}}
2+
3+
{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}}
4+
{{-- of this software and associated documentation files (the "Software"), to deal --}}
5+
{{-- in the Software without restriction, including without limitation the rights --}}
6+
{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}}
7+
{{-- copies of the Software, and to permit persons to whom the Software is --}}
8+
{{-- furnished to do so, subject to the following conditions: --}}
9+
10+
{{-- The above copyright notice and this permission notice shall be included in all --}}
11+
{{-- copies or substantial portions of the Software. --}}
12+
13+
{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}}
14+
{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}}
15+
{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}}
16+
{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}}
17+
{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}}
18+
{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}}
19+
{{-- SOFTWARE. --}}
20+
@extends('layouts.master')
21+
22+
@section('title')
23+
Databases
24+
@endsection
25+
26+
@section('content-header')
27+
<h1>Databases<small>All databases available for this server.</small></h1>
28+
<ol class="breadcrumb">
29+
<li><a href="{{ route('index') }}">{{ trans('strings.home') }}</a></li>
30+
<li><a href="{{ route('server.index', $server->uuidShort) }}">{{ $server->name }}</a></li>
31+
<li>{{ trans('strings.configuration') }}</li>
32+
<li class="active">{{ trans('strings.databases') }}</li>
33+
</ol>
34+
@endsection
35+
36+
@section('content')
37+
<div class="row">
38+
<div class="col-xs-12">
39+
<div class="box">
40+
<div class="box-header with-border">
41+
<h3 class="box-title">Your Databases</h3>
42+
</div>
43+
@if(count($databases) > 0)
44+
<div class="box-body table-responsive no-padding">
45+
<table class="table table-hover">
46+
<tbody>
47+
<tr>
48+
<th>Database</th>
49+
<th>Username</th>
50+
<th>Password</th>
51+
<th>MySQL Host</th>
52+
</tr>
53+
@foreach($databases as $database)
54+
<tr>
55+
<td>{{ $database->database }}</td>
56+
<td>{{ $database->username }}</td>
57+
<td><code>{{ Crypt::decrypt($database->password) }}</code>
58+
@can('reset-db-password', $server)
59+
<button class="btn btn-xs btn-primary pull-right" data-action="reset-database-password" data-id="{{ $database->id }}"><i class="fa fa-fw fa-refresh"></i> Reset Password</button>
60+
@endcan
61+
</td>
62+
<td><code>{{ $database->a_host }}:{{ $database->a_port }}</code></td>
63+
</tr>
64+
@endforeach
65+
</tbody>
66+
</table>
67+
</div>
68+
@else
69+
<div class="box-body">
70+
<div class="callout callout-info callout-nomargin">
71+
There are no databases listed for this server.
72+
@if(Auth::user()->root_admin === 1)
73+
<a href="{{ route('admin.servers.view', [
74+
'id' => $server->id,
75+
'tab' => 'tab_database'
76+
]) }}" target="_blank">Add a new database.</a>
77+
@endif
78+
</div>
79+
</div>
80+
@endif
81+
</div>
82+
</div>
83+
</div>
84+
@endsection
85+
86+
@section('footer-scripts')
87+
@parent
88+
{!! Theme::js('js/frontend/server.socket.js') !!}
89+
<script>
90+
@can('reset-db-password', $server)
91+
$('[data-action="reset-database-password"]').click(function (e) {
92+
e.preventDefault();
93+
var block = $(this);
94+
$(this).find('i').addClass('fa-spin');
95+
$.ajax({
96+
type: 'POST',
97+
url: Router.route('server.ajax.reset-database-password', { server: Pterodactyl.server.uuidShort }),
98+
headers: {
99+
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
100+
},
101+
data: {
102+
'database': $(this).data('id')
103+
}
104+
}).done(function (data) {
105+
block.parent().find('code').html(data);
106+
}).fail(function(jqXHR, textStatus, errorThrown) {
107+
console.error(jqXHR);
108+
var error = 'An error occured while trying to process this request.';
109+
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
110+
error = jqXHR.responseJSON.error;
111+
}
112+
swal({
113+
type: 'error',
114+
title: 'Whoops!',
115+
text: error
116+
});
117+
}).always(function () {
118+
block.find('i').removeClass('fa-spin');
119+
});
120+
});
121+
@endcan
122+
</script>
123+
@endsection

0 commit comments

Comments
 (0)