Return Http test cases to a passing state
This commit is contained in:
parent
eaae74fe33
commit
536180ed0c
26 changed files with 140 additions and 1113 deletions
|
@ -1,19 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Http\Middleware\API\Application;
|
||||
namespace Tests\Unit\Http\Middleware\Api\Application;
|
||||
|
||||
use Tests\Unit\Http\Middleware\MiddlewareTestCase;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Pterodactyl\Http\Middleware\Api\Application\AuthenticateApplicationUser;
|
||||
|
||||
class AuthenticateUserTest extends MiddlewareTestCase
|
||||
{
|
||||
/**
|
||||
* Test that no user defined results in an access denied exception.
|
||||
*
|
||||
* @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
|
||||
*/
|
||||
public function testNoUserDefined()
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
|
||||
$this->setRequestUserModel(null);
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
|
@ -21,11 +22,11 @@ class AuthenticateUserTest extends MiddlewareTestCase
|
|||
|
||||
/**
|
||||
* Test that a non-admin user results an an exception.
|
||||
*
|
||||
* @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
|
||||
*/
|
||||
public function testNonAdminUser()
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
|
||||
$this->generateRequestUserModel(['root_admin' => false]);
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
|
|
75
tests/Unit/Http/Middleware/Api/AuthenticateIPAccessTest.php
Normal file
75
tests/Unit/Http/Middleware/Api/AuthenticateIPAccessTest.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Http\Middleware\Api;
|
||||
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Tests\Unit\Http\Middleware\MiddlewareTestCase;
|
||||
use Pterodactyl\Http\Middleware\Api\AuthenticateIPAccess;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
|
||||
class AuthenticateIPAccessTest extends MiddlewareTestCase
|
||||
{
|
||||
/**
|
||||
* Test middleware when there are no IP restrictions.
|
||||
*/
|
||||
public function testWithNoIPRestrictions()
|
||||
{
|
||||
$model = factory(ApiKey::class)->make(['allowed_ips' => []]);
|
||||
$this->setRequestAttribute('api_key', $model);
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test middleware works correctly when a valid IP accesses
|
||||
* and there is an IP restriction.
|
||||
*/
|
||||
public function testWithValidIP()
|
||||
{
|
||||
$model = factory(ApiKey::class)->make(['allowed_ips' => '["127.0.0.1"]']);
|
||||
$this->setRequestAttribute('api_key', $model);
|
||||
|
||||
$this->request->shouldReceive('ip')->withNoArgs()->once()->andReturn('127.0.0.1');
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a CIDR range can be used.
|
||||
*/
|
||||
public function testValidIPAgainstCIDRRange()
|
||||
{
|
||||
$model = factory(ApiKey::class)->make(['allowed_ips' => '["192.168.1.1/28"]']);
|
||||
$this->setRequestAttribute('api_key', $model);
|
||||
|
||||
$this->request->shouldReceive('ip')->withNoArgs()->once()->andReturn('192.168.1.15');
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that an exception is thrown when an invalid IP address
|
||||
* tries to connect and there is an IP restriction.
|
||||
*/
|
||||
public function testWithInvalidIP()
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
|
||||
$model = factory(ApiKey::class)->make(['allowed_ips' => '["127.0.0.1"]']);
|
||||
$this->setRequestAttribute('api_key', $model);
|
||||
|
||||
$this->request->shouldReceive('ip')->withNoArgs()->twice()->andReturn('127.0.0.2');
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the middleware to be used when testing.
|
||||
*
|
||||
* @return \Pterodactyl\Http\Middleware\Api\AuthenticateIPAccess
|
||||
*/
|
||||
private function getMiddleware(): AuthenticateIPAccess
|
||||
{
|
||||
return new AuthenticateIPAccess();
|
||||
}
|
||||
}
|
171
tests/Unit/Http/Middleware/Api/AuthenticateKeyTest.php
Normal file
171
tests/Unit/Http/Middleware/Api/AuthenticateKeyTest.php
Normal file
|
@ -0,0 +1,171 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Http\Middleware\Api;
|
||||
|
||||
use Mockery as m;
|
||||
use Cake\Chronos\Chronos;
|
||||
use Pterodactyl\Models\User;
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Illuminate\Auth\AuthManager;
|
||||
use Illuminate\Contracts\Encryption\Encrypter;
|
||||
use Tests\Unit\Http\Middleware\MiddlewareTestCase;
|
||||
use Pterodactyl\Http\Middleware\Api\AuthenticateKey;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
||||
use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
|
||||
class AuthenticateKeyTest extends MiddlewareTestCase
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Auth\AuthManager|\Mockery\Mock
|
||||
*/
|
||||
private $auth;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Encryption\Encrypter|\Mockery\Mock
|
||||
*/
|
||||
private $encrypter;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface|\Mockery\Mock
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Setup tests.
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
Chronos::setTestNow(Chronos::now());
|
||||
|
||||
$this->auth = m::mock(AuthManager::class);
|
||||
$this->encrypter = m::mock(Encrypter::class);
|
||||
$this->repository = m::mock(ApiKeyRepositoryInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a missing bearer token will throw an exception.
|
||||
*/
|
||||
public function testMissingBearerTokenThrowsException()
|
||||
{
|
||||
$this->request->shouldReceive('user')->andReturnNull();
|
||||
$this->request->shouldReceive('bearerToken')->withNoArgs()->once()->andReturnNull();
|
||||
|
||||
try {
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions(), ApiKey::TYPE_APPLICATION);
|
||||
} catch (HttpException $exception) {
|
||||
$this->assertEquals(401, $exception->getStatusCode());
|
||||
$this->assertEquals(['WWW-Authenticate' => 'Bearer'], $exception->getHeaders());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that an invalid API identifier throws an exception.
|
||||
*/
|
||||
public function testInvalidIdentifier()
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
|
||||
$this->request->shouldReceive('bearerToken')->withNoArgs()->twice()->andReturn('abcd1234');
|
||||
$this->repository->shouldReceive('findFirstWhere')->andThrow(new RecordNotFoundException);
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions(), ApiKey::TYPE_APPLICATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a valid token can continue past the middleware.
|
||||
*/
|
||||
public function testValidToken()
|
||||
{
|
||||
$model = factory(ApiKey::class)->make();
|
||||
|
||||
$this->request->shouldReceive('bearerToken')->withNoArgs()->twice()->andReturn($model->identifier . 'decrypted');
|
||||
$this->repository->shouldReceive('findFirstWhere')->with([
|
||||
['identifier', '=', $model->identifier],
|
||||
['key_type', '=', ApiKey::TYPE_APPLICATION],
|
||||
])->once()->andReturn($model);
|
||||
$this->encrypter->shouldReceive('decrypt')->with($model->token)->once()->andReturn('decrypted');
|
||||
$this->auth->shouldReceive('guard->loginUsingId')->with($model->user_id)->once()->andReturnNull();
|
||||
|
||||
$this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [
|
||||
'last_used_at' => Chronos::now(),
|
||||
])->once()->andReturnNull();
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions(), ApiKey::TYPE_APPLICATION);
|
||||
$this->assertEquals($model, $this->request->attributes->get('api_key'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a valid token can continue past the middleware when set as a user token.
|
||||
*/
|
||||
public function testValidTokenWithUserKey()
|
||||
{
|
||||
$model = factory(ApiKey::class)->make();
|
||||
|
||||
$this->request->shouldReceive('bearerToken')->withNoArgs()->twice()->andReturn($model->identifier . 'decrypted');
|
||||
$this->repository->shouldReceive('findFirstWhere')->with([
|
||||
['identifier', '=', $model->identifier],
|
||||
['key_type', '=', ApiKey::TYPE_ACCOUNT],
|
||||
])->once()->andReturn($model);
|
||||
$this->encrypter->shouldReceive('decrypt')->with($model->token)->once()->andReturn('decrypted');
|
||||
$this->auth->shouldReceive('guard->loginUsingId')->with($model->user_id)->once()->andReturnNull();
|
||||
|
||||
$this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [
|
||||
'last_used_at' => Chronos::now(),
|
||||
])->once()->andReturnNull();
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions(), ApiKey::TYPE_ACCOUNT);
|
||||
$this->assertEquals($model, $this->request->attributes->get('api_key'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can still make it though this middleware if the user is logged in and passing
|
||||
* through a cookie.
|
||||
*/
|
||||
public function testAccessWithoutToken()
|
||||
{
|
||||
$user = factory(User::class)->make(['id' => 123]);
|
||||
|
||||
$this->request->shouldReceive('user')->andReturn($user);
|
||||
$this->request->shouldReceive('bearerToken')->withNoArgs()->twice()->andReturnNull();
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions(), ApiKey::TYPE_ACCOUNT);
|
||||
$model = $this->request->attributes->get('api_key');
|
||||
|
||||
$this->assertSame(ApiKey::TYPE_ACCOUNT, $model->key_type);
|
||||
$this->assertSame(123, $model->user_id);
|
||||
$this->assertNull($model->identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a valid token identifier with an invalid token attached to it
|
||||
* triggers an exception.
|
||||
*/
|
||||
public function testInvalidTokenForIdentifier()
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
|
||||
$model = factory(ApiKey::class)->make();
|
||||
|
||||
$this->request->shouldReceive('bearerToken')->withNoArgs()->twice()->andReturn($model->identifier . 'asdf');
|
||||
$this->repository->shouldReceive('findFirstWhere')->with([
|
||||
['identifier', '=', $model->identifier],
|
||||
['key_type', '=', ApiKey::TYPE_APPLICATION],
|
||||
])->once()->andReturn($model);
|
||||
$this->encrypter->shouldReceive('decrypt')->with($model->token)->once()->andReturn('decrypted');
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions(), ApiKey::TYPE_APPLICATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the middleware with mocked dependencies for testing.
|
||||
*
|
||||
* @return \Pterodactyl\Http\Middleware\Api\AuthenticateKey
|
||||
*/
|
||||
private function getMiddleware(): AuthenticateKey
|
||||
{
|
||||
return new AuthenticateKey($this->repository, $this->auth, $this->encrypter);
|
||||
}
|
||||
}
|
|
@ -4,19 +4,27 @@ namespace Tests\Unit\Http\Middleware\Api\Daemon;
|
|||
|
||||
use Mockery as m;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Illuminate\Contracts\Encryption\Encrypter;
|
||||
use Tests\Unit\Http\Middleware\MiddlewareTestCase;
|
||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
|
||||
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
||||
use Pterodactyl\Http\Middleware\Api\Daemon\DaemonAuthenticate;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
|
||||
class DaemonAuthenticateTest extends MiddlewareTestCase
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface|\Mockery\Mock
|
||||
* @var \Mockery\MockInterface
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Mockery\MockInterface
|
||||
*/
|
||||
private $encrypter;
|
||||
|
||||
/**
|
||||
* Setup tests.
|
||||
*/
|
||||
|
@ -24,7 +32,8 @@ class DaemonAuthenticateTest extends MiddlewareTestCase
|
|||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->repository = m::mock(NodeRepositoryInterface::class);
|
||||
$this->encrypter = m::mock(Encrypter::class);
|
||||
$this->repository = m::mock(NodeRepository::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,7 +42,7 @@ class DaemonAuthenticateTest extends MiddlewareTestCase
|
|||
*/
|
||||
public function testResponseShouldContinueIfRouteIsExempted()
|
||||
{
|
||||
$this->request->shouldReceive('route->getName')->withNoArgs()->once()->andReturn('daemon.configuration');
|
||||
$this->request->expects('route->getName')->withNoArgs()->andReturn('daemon.configuration');
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
}
|
||||
|
@ -44,8 +53,8 @@ class DaemonAuthenticateTest extends MiddlewareTestCase
|
|||
*/
|
||||
public function testResponseShouldFailIfNoTokenIsProvided()
|
||||
{
|
||||
$this->request->shouldReceive('route->getName')->withNoArgs()->once()->andReturn('random.route');
|
||||
$this->request->shouldReceive('bearerToken')->withNoArgs()->once()->andReturnNull();
|
||||
$this->request->expects('route->getName')->withNoArgs()->andReturn('random.route');
|
||||
$this->request->expects('bearerToken')->withNoArgs()->andReturnNull();
|
||||
|
||||
try {
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
|
@ -58,17 +67,54 @@ class DaemonAuthenticateTest extends MiddlewareTestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* Test that passing in an invalid node daemon secret will result in a HTTP/403
|
||||
* error response.
|
||||
* Test that passing in an invalid node daemon secret will result in a bad request
|
||||
* exception being returned.
|
||||
*
|
||||
* @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
|
||||
* @param string $token
|
||||
* @dataProvider badTokenDataProvider
|
||||
*/
|
||||
public function testResponseShouldFailIfNoNodeIsFound()
|
||||
public function testResponseShouldFailIfTokenFormatIsIncorrect(string $token)
|
||||
{
|
||||
$this->request->shouldReceive('route->getName')->withNoArgs()->once()->andReturn('random.route');
|
||||
$this->request->shouldReceive('bearerToken')->withNoArgs()->once()->andReturn('test1234');
|
||||
$this->expectException(BadRequestHttpException::class);
|
||||
|
||||
$this->repository->shouldReceive('findFirstWhere')->with([['daemonSecret', '=', 'test1234']])->once()->andThrow(new RecordNotFoundException);
|
||||
$this->request->expects('route->getName')->withNoArgs()->andReturn('random.route');
|
||||
$this->request->expects('bearerToken')->withNoArgs()->andReturn($token);
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that an access denied error is returned if the node is valid but the token
|
||||
* provided is not valid.
|
||||
*/
|
||||
public function testResponseShouldFailIfTokenIsNotValid()
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
|
||||
/** @var \Pterodactyl\Models\Node $model */
|
||||
$model = factory(Node::class)->make();
|
||||
|
||||
$this->request->expects('route->getName')->withNoArgs()->andReturn('random.route');
|
||||
$this->request->expects('bearerToken')->withNoArgs()->andReturn($model->daemon_token_id . '.random_string_123');
|
||||
|
||||
$this->repository->expects('findFirstWhere')->with(['daemon_token_id' => $model->daemon_token_id])->andReturn($model);
|
||||
$this->encrypter->expects('decrypt')->with($model->daemon_token)->andReturns(decrypt($model->daemon_token));
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that an access denied exception is returned if the node is not found using
|
||||
* the token ID provided.
|
||||
*/
|
||||
public function testResponseShouldFailIfNodeIsNotFound()
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
|
||||
$this->request->expects('route->getName')->withNoArgs()->andReturn('random.route');
|
||||
$this->request->expects('bearerToken')->withNoArgs()->andReturn('abcd1234.random_string_123');
|
||||
|
||||
$this->repository->expects('findFirstWhere')->with(['daemon_token_id' => 'abcd1234'])->andThrow(RecordNotFoundException::class);
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
}
|
||||
|
@ -78,18 +124,39 @@ class DaemonAuthenticateTest extends MiddlewareTestCase
|
|||
*/
|
||||
public function testSuccessfulMiddlewareProcess()
|
||||
{
|
||||
/** @var \Pterodactyl\Models\Node $model */
|
||||
$model = factory(Node::class)->make();
|
||||
|
||||
$this->request->shouldReceive('route->getName')->withNoArgs()->once()->andReturn('random.route');
|
||||
$this->request->shouldReceive('bearerToken')->withNoArgs()->once()->andReturn($model->daemonSecret);
|
||||
$this->request->expects('route->getName')->withNoArgs()->andReturn('random.route');
|
||||
$this->request->expects('bearerToken')->withNoArgs()->andReturn($model->daemon_token_id . '.' . decrypt($model->daemon_token));
|
||||
|
||||
$this->repository->shouldReceive('findFirstWhere')->with([['daemonSecret', '=', $model->daemonSecret]])->once()->andReturn($model);
|
||||
$this->repository->expects('findFirstWhere')->with(['daemon_token_id' => $model->daemon_token_id])->andReturn($model);
|
||||
$this->encrypter->expects('decrypt')->with($model->daemon_token)->andReturns(decrypt($model->daemon_token));
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
$this->assertRequestHasAttribute('node');
|
||||
$this->assertRequestAttributeEquals($model, 'node');
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides different tokens that should trigger a bad request exception due to
|
||||
* their formatting.
|
||||
*
|
||||
* @return array|\string[][]
|
||||
*/
|
||||
public function badTokenDataProvider(): array
|
||||
{
|
||||
return [
|
||||
['foo'],
|
||||
['foobar'],
|
||||
['foo-bar'],
|
||||
['foo.bar.baz'],
|
||||
['.foo'],
|
||||
['foo.'],
|
||||
['foo..bar'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the middleware using mocked dependencies.
|
||||
*
|
||||
|
@ -97,6 +164,6 @@ class DaemonAuthenticateTest extends MiddlewareTestCase
|
|||
*/
|
||||
private function getMiddleware(): DaemonAuthenticate
|
||||
{
|
||||
return new DaemonAuthenticate($this->repository);
|
||||
return new DaemonAuthenticate($this->encrypter, $this->repository);
|
||||
}
|
||||
}
|
||||
|
|
46
tests/Unit/Http/Middleware/Api/SetSessionDriverTest.php
Normal file
46
tests/Unit/Http/Middleware/Api/SetSessionDriverTest.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Http\Middleware\Api;
|
||||
|
||||
use Mockery as m;
|
||||
use Illuminate\Contracts\Config\Repository;
|
||||
use Tests\Unit\Http\Middleware\MiddlewareTestCase;
|
||||
use Pterodactyl\Http\Middleware\Api\SetSessionDriver;
|
||||
|
||||
class SetSessionDriverTest extends MiddlewareTestCase
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Config\Repository|\Mockery\Mock
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Setup tests.
|
||||
*/
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->config = m::mock(Repository::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a production environment does not try to disable debug bar.
|
||||
*/
|
||||
public function testMiddleware()
|
||||
{
|
||||
$this->config->shouldReceive('set')->once()->with('session.driver', 'array')->andReturnNull();
|
||||
|
||||
$this->getMiddleware()->handle($this->request, $this->getClosureAssertions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the middleware with mocked dependencies for testing.
|
||||
*
|
||||
* @return \Pterodactyl\Http\Middleware\Api\SetSessionDriver
|
||||
*/
|
||||
private function getMiddleware(): SetSessionDriver
|
||||
{
|
||||
return new SetSessionDriver($this->config);
|
||||
}
|
||||
}
|
Reference in a new issue