Skip to content

Commit cbdf4d4

Browse files
committed
Merge branch 'feature/vuejs' into feature/move-to-webpack
2 parents 6ed46c2 + 5bcabbd commit cbdf4d4

File tree

16 files changed

+270
-232
lines changed

16 files changed

+270
-232
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Controllers\Api\Client;
4+
5+
use Illuminate\Http\Request;
6+
use Pterodactyl\Transformers\Api\Client\AccountTransformer;
7+
8+
class AccountController extends ClientApiController
9+
{
10+
public function index(Request $request): array
11+
{
12+
return $this->fractal->item($request->user())
13+
->transformWith($this->getTransformer(AccountTransformer::class))
14+
->toArray();
15+
}
16+
}

app/Http/Controllers/Auth/AbstractLoginController.php

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Pterodactyl\Http\Controllers\Auth;
44

5-
use Cake\Chronos\Chronos;
65
use Lcobucci\JWT\Builder;
76
use Illuminate\Http\Request;
87
use Pterodactyl\Models\User;
@@ -16,6 +15,7 @@
1615
use Illuminate\Contracts\Encryption\Encrypter;
1716
use Illuminate\Foundation\Auth\AuthenticatesUsers;
1817
use Pterodactyl\Traits\Helpers\ProvidesJWTServices;
18+
use Pterodactyl\Transformers\Api\Client\AccountTransformer;
1919
use Illuminate\Contracts\Cache\Repository as CacheRepository;
2020
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
2121

@@ -137,24 +137,18 @@ protected function sendLoginResponse(User $user, Request $request): JsonResponse
137137
$request->session()->regenerate();
138138
$this->clearLoginAttempts($request);
139139

140-
$token = $this->builder->setIssuer(config('app.url'))
141-
->setAudience(config('app.url'))
142-
->setId(str_random(12), true)
143-
->setIssuedAt(Chronos::now()->getTimestamp())
144-
->setNotBefore(Chronos::now()->getTimestamp())
145-
->setExpiration(Chronos::now()->addSeconds(config('session.lifetime'))->getTimestamp())
146-
->set('user', $user->only([
147-
'id', 'uuid', 'username', 'email', 'name_first', 'name_last', 'language', 'root_admin',
148-
]))
149-
->sign($this->getJWTSigner(), $this->getJWTSigningKey())
150-
->getToken();
151-
152140
$this->auth->guard()->login($user, true);
153141

142+
debug($request->cookies->all());
143+
154144
return response()->json([
155145
'complete' => true,
156146
'intended' => $this->redirectPath(),
157-
'token' => $token->__toString(),
147+
'cookie' => [
148+
'name' => config('session.cookie'),
149+
'value' => $this->encrypter->encrypt($request->cookie(config('session.cookie'))),
150+
],
151+
'user' => (new AccountTransformer())->transform($user),
158152
]);
159153
}
160154

app/Http/Kernel.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Pterodactyl\Http;
44

5-
use Pterodactyl\Http\Middleware\MaintenanceMiddleware;
65
use Pterodactyl\Models\ApiKey;
76
use Illuminate\Auth\Middleware\Authorize;
87
use Illuminate\Auth\Middleware\Authenticate;
@@ -21,6 +20,7 @@
2120
use Pterodactyl\Http\Middleware\AccessingValidServer;
2221
use Pterodactyl\Http\Middleware\Api\SetSessionDriver;
2322
use Illuminate\View\Middleware\ShareErrorsFromSession;
23+
use Pterodactyl\Http\Middleware\MaintenanceMiddleware;
2424
use Pterodactyl\Http\Middleware\RedirectIfAuthenticated;
2525
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
2626
use Pterodactyl\Http\Middleware\Api\AuthenticateIPAccess;
@@ -71,15 +71,17 @@ class Kernel extends HttpKernel
7171
RequireTwoFactorAuthentication::class,
7272
],
7373
'api' => [
74-
'throttle:120,1',
74+
'throttle:240,1',
7575
ApiSubstituteBindings::class,
7676
SetSessionDriver::class,
7777
'api..key:' . ApiKey::TYPE_APPLICATION,
7878
AuthenticateApplicationUser::class,
7979
AuthenticateIPAccess::class,
8080
],
8181
'client-api' => [
82-
'throttle:60,1',
82+
'throttle:240,1',
83+
EncryptCookies::class,
84+
StartSession::class,
8385
SubstituteClientApiBindings::class,
8486
SetSessionDriver::class,
8587
'api..key:' . ApiKey::TYPE_ACCOUNT,

app/Http/Middleware/Api/AuthenticateKey.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Closure;
66
use Lcobucci\JWT\Parser;
77
use Cake\Chronos\Chronos;
8+
use Illuminate\Support\Str;
89
use Illuminate\Http\Request;
910
use Pterodactyl\Models\ApiKey;
1011
use Illuminate\Auth\AuthManager;
@@ -63,19 +64,24 @@ public function __construct(ApiKeyRepositoryInterface $repository, AuthManager $
6364
public function handle(Request $request, Closure $next, int $keyType)
6465
{
6566
if (is_null($request->bearerToken())) {
66-
throw new HttpException(401, null, null, ['WWW-Authenticate' => 'Bearer']);
67+
if (! Str::startsWith($request->route()->getName(), ['api.client']) && ! $request->user()) {
68+
throw new HttpException(401, null, null, ['WWW-Authenticate' => 'Bearer']);
69+
}
6770
}
6871

69-
$raw = $request->bearerToken();
72+
if (is_null($request->bearerToken())) {
73+
$model = (new ApiKey)->forceFill([
74+
'user_id' => $request->user()->id,
75+
'key_type' => ApiKey::TYPE_ACCOUNT,
76+
]);
77+
}
7078

71-
// This is an internal JWT, treat it differently to get the correct user before passing it along.
72-
if (strlen($raw) > ApiKey::IDENTIFIER_LENGTH + ApiKey::KEY_LENGTH) {
73-
$model = $this->authenticateJWT($raw);
74-
} else {
79+
if (! isset($model)) {
80+
$raw = $request->bearerToken();
7581
$model = $this->authenticateApiKey($raw, $keyType);
82+
$this->auth->guard()->loginUsingId($model->user_id);
7683
}
7784

78-
$this->auth->guard()->loginUsingId($model->user_id);
7985
$request->attributes->set('api_key', $model);
8086

8187
return $next($request);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Pterodactyl\Transformers\Api\Client;
4+
5+
use Pterodactyl\Models\User;
6+
7+
class AccountTransformer extends BaseClientTransformer
8+
{
9+
/**
10+
* Return the resource name for the JSONAPI output.
11+
*
12+
* @return string
13+
*/
14+
public function getResourceName(): string
15+
{
16+
return 'user';
17+
}
18+
19+
/**
20+
* Return basic information about the currently logged in user.
21+
*
22+
* @param \Pterodactyl\Models\User $model
23+
* @return array
24+
*/
25+
public function transform(User $model)
26+
{
27+
return [
28+
'admin' => $model->root_admin,
29+
'username' => $model->username,
30+
'email' => $model->email,
31+
'first_name' => $model->name_first,
32+
'last_name' => $model->name_last,
33+
'language' => $model->language,
34+
];
35+
}
36+
}

resources/assets/scripts/app.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,24 @@ import Vuex from 'vuex';
33
import vuexI18n from 'vuex-i18n';
44
import VueRouter from 'vue-router';
55

6+
require('./bootstrap');
7+
68
// Helpers
79
import { Ziggy } from './helpers/ziggy';
810
import Locales from './../../../resources/lang/locales';
911
import { flash } from './mixins/flash';
1012
import { routes } from './routes';
11-
import { storeData } from './store';
13+
import storeData from './store/index.js';
1214

1315
window.events = new Vue;
1416
window.Ziggy = Ziggy;
1517

18+
Vue.config.productionTip = false;
1619
Vue.use(Vuex);
20+
1721
const store = new Vuex.Store(storeData);
1822
const route = require('./../../../vendor/tightenco/ziggy/src/js/route').default;
1923

20-
Vue.config.productionTip = false;
2124
Vue.mixin({ methods: { route } });
2225
Vue.mixin(flash);
2326

@@ -31,6 +34,4 @@ const router = new VueRouter({
3134
mode: 'history', routes
3235
});
3336

34-
require('./bootstrap');
35-
3637
const app = new Vue({ store, router }).$mount('#pterodactyl');

resources/assets/scripts/bootstrap.js

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import axios from './helpers/axios';
2+
13
window._ = require('lodash');
24

35
/**
@@ -10,24 +12,7 @@ try {
1012
window.$ = window.jQuery = require('jquery');
1113
} catch (e) {}
1214

13-
/**
14-
* We'll load the axios HTTP library which allows us to easily issue requests
15-
* to our Laravel back-end. This library automatically handles sending the
16-
* CSRF token as a header based on the value of the "XSRF" token cookie.
17-
*/
18-
19-
window.axios = require('axios');
20-
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
21-
window.axios.defaults.headers.common['Accept'] = 'application/json';
22-
window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.token || '';
23-
24-
if (typeof phpdebugbar !== 'undefined') {
25-
window.axios.interceptors.response.use(function (response) {
26-
phpdebugbar.ajaxHandler.handle(response.request);
27-
28-
return response;
29-
});
30-
}
15+
window.axios = axios;
3116

3217
/**
3318
* Next we will register the CSRF Token as a common header with Axios so that

resources/assets/scripts/components/auth/LoginForm.vue

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -77,32 +77,21 @@
7777
this.$data.showSpinner = true;
7878
7979
this.clearFlashes();
80-
axios.post(this.route('auth.login'), {
81-
user: this.$props.user.email,
82-
password: this.$props.user.password,
83-
})
84-
.then(function (response) {
85-
// If there is a 302 redirect or some other odd behavior (basically, response that isnt
86-
// in JSON format) throw an error and don't try to continue with the login.
87-
if (!(response.data instanceof Object)) {
88-
throw new Error('An error was encountered while processing this request.');
80+
this.$store.dispatch('auth/login', { user: this.$props.user.email, password: this.$props.user.password })
81+
.then(response => {
82+
if (response.complete) {
83+
return window.location = response.intended;
8984
}
9085
91-
if (response.data.complete) {
92-
localStorage.setItem('token', response.data.token);
93-
self.$store.dispatch('login');
94-
return window.location = response.data.intended;
95-
}
96-
97-
self.$props.user.password = '';
98-
self.$data.showSpinner = false;
99-
self.$router.push({name: 'checkpoint', query: {token: response.data.login_token}});
86+
this.$props.user.password = '';
87+
this.$data.showSpinner = false;
88+
this.$router.push({name: 'checkpoint', query: {token: response.login_token}});
10089
})
101-
.catch(function (err) {
102-
self.$props.user.password = '';
103-
self.$data.showSpinner = false;
104-
self.$refs.password.focus();
105-
self.$store.dispatch('logout');
90+
.catch(err => {
91+
this.$props.user.password = '';
92+
this.$data.showSpinner = false;
93+
this.$refs.password.focus();
94+
this.$store.dispatch('auth/logout');
10695
10796
if (!err.response) {
10897
return console.error(err);

resources/assets/scripts/components/dashboard/Dashboard.vue

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
</div>
1919
<transition-group class="w-full m-auto mt-4 animate fadein sm:flex flex-wrap content-start" v-else>
2020
<server-box
21-
v-for="(server, index) in servers.models"
21+
v-for="(server, index) in servers"
2222
v-bind:key="index"
2323
v-bind:server="server"
2424
/>
@@ -29,7 +29,7 @@
2929

3030
<script>
3131
import { DateTime } from 'luxon';
32-
import { ServerCollection } from '../../models/server';
32+
import Server from '../../models/server';
3333
import _ from 'lodash';
3434
import Flash from '../Flash';
3535
import ServerBox from './ServerBox';
@@ -44,7 +44,7 @@
4444
documentVisible: true,
4545
loading: true,
4646
search: '',
47-
servers: new ServerCollection,
47+
servers: [],
4848
}
4949
},
5050
@@ -83,14 +83,14 @@
8383
this.clearFlashes();
8484
})
8585
.then(response => {
86-
this.servers = new ServerCollection;
86+
this.servers = [];
8787
response.data.data.forEach(obj => {
88-
this.getResourceUse(
89-
this.servers.add(obj.attributes)
90-
);
88+
const s = new Server(obj.attributes);
89+
this.servers.push(s);
90+
this.getResourceUse(s);
9191
});
9292
93-
if (this.servers.models.length === 0) {
93+
if (this.servers.length === 0) {
9494
this.info(this.$t('dashboard.index.no_matches'));
9595
}
9696
})

0 commit comments

Comments
 (0)