Skip to content

Commit e7436aa

Browse files
committed
Add active session management
1 parent 8190f08 commit e7436aa

File tree

5 files changed

+113
-13
lines changed

5 files changed

+113
-13
lines changed

app/Http/Controllers/Base/IndexController.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
use Google2FA;
3030
use Alert;
3131

32-
use Pterodactyl\Models\Server;
32+
use Pterodactyl\Models;
3333
use Pterodactyl\Exceptions\DisplayException;
3434

3535
use Pterodactyl\Http\Controllers\Controller;
@@ -55,7 +55,7 @@ public function __construct()
5555
public function getIndex(Request $request)
5656
{
5757
return view('base.index', [
58-
'servers' => Server::getUserServers(10),
58+
'servers' => Models\Server::getUserServers(10),
5959
]);
6060
}
6161

@@ -72,14 +72,16 @@ public function getPassword(Request $request, $length = 16)
7272
}
7373

7474
/**
75-
* Returns TOTP Management Page.
75+
* Returns Security Management Page.
7676
*
7777
* @param \Illuminate\Http\Request $request
7878
* @return \Illuminate\Contracts\View\View
7979
*/
80-
public function getAccountTotp(Request $request)
80+
public function getAccountSecurity(Request $request)
8181
{
82-
return view('base.totp');
82+
return view('base.security', [
83+
'sessions' => Models\Session::where('user_id', Auth::user()->id)->get()
84+
]);
8385
}
8486

8587
/**
@@ -227,4 +229,11 @@ public function postAccountPassword(Request $request)
227229

228230
}
229231

232+
public function getRevokeSession(Request $request, $id)
233+
{
234+
$session = Models\Session::where('id', $id)->where('user_id', Auth::user()->id)->firstOrFail();
235+
$session->delete();
236+
return redirect()->route('account.security');
237+
}
238+
230239
}

app/Http/Routes/BaseRoutes.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,19 @@ public function map(Router $router) {
7171

7272
// TOTP Routes
7373
$router->group([
74-
'prefix' => 'account/totp',
74+
'prefix' => 'account/security',
7575
'middleware' => [
7676
'auth',
7777
'csrf'
7878
]
7979
], function () use ($router) {
8080
$router->get('/', [
81-
'as' => 'account.totp',
82-
'uses' => 'Base\IndexController@getAccountTotp'
81+
'as' => 'account.security',
82+
'uses' => 'Base\IndexController@getAccountSecurity'
83+
]);
84+
$router->get('/revoke/{id}', [
85+
'as' => 'account.security.revoke',
86+
'uses' => 'Base\IndexController@getRevokeSession'
8387
]);
8488
$router->put('/', [
8589
'uses' => 'Base\IndexController@putAccountTotp'

app/Models/Session.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
namespace Pterodactyl\Models;
25+
26+
use Illuminate\Database\Eloquent\Model;
27+
28+
class Session extends Model
29+
{
30+
31+
/**
32+
* The table associated with the model.
33+
*
34+
* @var string
35+
*/
36+
protected $table = 'sessions';
37+
38+
/**
39+
* Cast values to correct type.
40+
*
41+
* @var array
42+
*/
43+
protected $casts = [
44+
'id' => 'string',
45+
'user_id' => 'integer',
46+
];
47+
48+
}
Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
{{-- SOFTWARE. --}}
2020
@extends('layouts.master')
2121

22-
@section('title', 'Account TOTP Settings')
22+
@section('title', 'Account Security')
2323

2424
@section('sidebar-server')
2525
@endsection
@@ -34,7 +34,46 @@
3434
</div>
3535
@endforeach
3636
@endforeach
37-
<h3 style="margin-top:0;">{{ trans('base.account.totp_header') }} <small>@if (Auth::user()->use_totp === 1){{ trans('strings.enabled') }}@else{{ trans('strings.disabled') }}@endif</small></h3><hr />
37+
<h3 style="margin-top:0;">Active Sessions</h3><hr />
38+
<table class="table table-bordered table-hover" style="margin-bottom:0;">
39+
<thead>
40+
<tr>
41+
<th>Session ID</th>
42+
<th>IP Address</th>
43+
<th>User Agent</th>
44+
<th>Last Location</th>
45+
<th>Last Activity</th>
46+
<th></th>
47+
</th>
48+
</thead>
49+
<tbody>
50+
@foreach($sessions as $session)
51+
<tr>
52+
<?php $prev = unserialize(base64_decode($session->payload)) ?>
53+
<td><code>{{ substr($session->id, 0, 8) }}</code></td>
54+
<td>{{ $session->ip_address }}</td>
55+
<td><small>{{ $session->user_agent }}</small></td>
56+
<td>
57+
@if(isset($prev['_previous']['url']))
58+
{{ str_replace(env('APP_URL'), '', $prev['_previous']['url']) }}
59+
@else
60+
<em>unknwon</em>
61+
@endif
62+
</td>
63+
<td>
64+
@if((time() - $session->last_activity < 10))
65+
<em>just now</em>
66+
@else
67+
{{ date('D, M j \a\t H:i:s', $session->last_activity) }}
68+
@endif
69+
</td>
70+
<td><a href="{{ route('account.security.revoke', $session->id) }}"><i class="fa fa-trash-o"></i></a></td>
71+
</tr>
72+
@endforeach
73+
</tbody>
74+
</table>
75+
76+
<h3>{{ trans('base.account.totp_header') }} <small>@if (Auth::user()->use_totp === 1){{ trans('strings.enabled') }}@else{{ trans('strings.disabled') }}@endif</small></h3><hr />
3877
@if (Auth::user()->use_totp === 1)
3978
<div class="panel panel-default">
4079
<div class="panel-heading">{{ trans('base.account.totp_disable') }}</div>
@@ -112,7 +151,7 @@
112151
</div>
113152
<script>
114153
$(document).ready(function () {
115-
$('#sidebar_links').find('a[href=\'/account/totp\']').addClass('active');
154+
$('#sidebar_links').find('a[href=\'/account/security\']').addClass('active');
116155
117156
$('#close_reload').click(function () {
118157
location.reload();

resources/views/layouts/master.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@
182182
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ trans('pagination.sidebar.account_controls') }} <b class="caret"></b></a>
183183
<ul class="dropdown-menu">
184184
<li><a href="/account">{{ trans('pagination.sidebar.account_settings') }}</a></li>
185-
<li><a href="/account/totp">{{ trans('pagination.sidebar.account_security') }}</a></li>
185+
<li><a href="/account/security">{{ trans('pagination.sidebar.account_security') }}</a></li>
186186
<li><a href="/index">{{ trans('pagination.sidebar.servers') }}</a></li>
187187
</ul>
188188
</li>
@@ -239,7 +239,7 @@
239239
<div class="list-group">
240240
<a href="#" class="list-group-item list-group-item-heading"><strong>{{ trans('pagination.sidebar.account_controls') }}</strong></a>
241241
<a href="/account" class="list-group-item">{{ trans('pagination.sidebar.account_settings') }}</a>
242-
<a href="/account/totp" class="list-group-item">{{ trans('pagination.sidebar.account_security') }}</a>
242+
<a href="/account/security" class="list-group-item">{{ trans('pagination.sidebar.account_security') }}</a>
243243
<a href="/" class="list-group-item">{{ trans('pagination.sidebar.servers') }}</a>
244244
</div>
245245
@section('sidebar-server')

0 commit comments

Comments
 (0)