diff --git a/app/Enums/ResourceLimit.php b/app/Enums/ResourceLimit.php new file mode 100644 index 000000000..59707601a --- /dev/null +++ b/app/Enums/ResourceLimit.php @@ -0,0 +1,65 @@ +name}"; + } + + /** + * Returns a middleware that will throttle the specific resource by server. This + * throttle applies to any user making changes to that resource on the specific + * server, it is NOT per-user. + */ + public function middleware(): string + { + return ThrottleRequests::using($this->throttleKey()); + } + + public function limit(): Limit + { + return match ($this) { + self::Websocket => Limit::perMinute(5), + self::BackupRestore => Limit::perMinutes(15, 3), + self::DatabaseCreate => Limit::perMinute(2), + self::SubuserCreate => Limit::perMinutes(15, 10), + self::FilePull => Limit::perMinutes(10, 5), + default => Limit::perMinute(2), + }; + } + + public static function boot(): void + { + foreach (self::cases() as $case) { + RateLimiter::for($case->throttleKey(), function (Request $request) use ($case) { + Assert::isInstanceOf($server = $request->route()->parameter('server'), Server::class); + + return $case->limit()->by($server->uuid); + }); + } + } +} diff --git a/app/Extensions/OAuth/Schemas/GithubSchema.php b/app/Extensions/OAuth/Schemas/GithubSchema.php index c3dfc4894..b7258ab4b 100644 --- a/app/Extensions/OAuth/Schemas/GithubSchema.php +++ b/app/Extensions/OAuth/Schemas/GithubSchema.php @@ -18,11 +18,11 @@ final class GithubSchema extends OAuthSchema public function getSetupSteps(): array { return array_merge([ - Step::make('Register new Github OAuth App') + Step::make('Register new GitHub OAuth App') ->schema([ TextEntry::make('create_application') ->hiddenLabel() - ->state(new HtmlString(Blade::render('

Visit the Github Developer Dashboard, go to OAuth Apps and click on New OAuth App.

Enter an Application name (e.g. your panel name), set Homepage URL to your panel url and enter the below url as Authorization callback URL.

'))), + ->state(new HtmlString(Blade::render('

Visit the GitHub Developer Dashboard, go to OAuth Apps and click on New OAuth App.

Enter an Application name (e.g. your panel name), set Homepage URL to your panel url and enter the below url as Authorization callback URL.

'))), TextInput::make('_noenv_callback') ->label('Authorization callback URL') ->dehydrated() diff --git a/app/Filament/Admin/Resources/Nodes/Pages/CreateNode.php b/app/Filament/Admin/Resources/Nodes/Pages/CreateNode.php index 5850bc8b8..b5de18d5d 100644 --- a/app/Filament/Admin/Resources/Nodes/Pages/CreateNode.php +++ b/app/Filament/Admin/Resources/Nodes/Pages/CreateNode.php @@ -253,13 +253,11 @@ class CreateNode extends CreateRecord ->columnSpan(2), TextInput::make('upload_size') ->label(trans('admin/node.upload_limit')) - ->helperText(trans('admin/node.upload_limit_help.0')) - ->hintIcon('tabler-question-mark', trans('admin/node.upload_limit_help.1')) + ->hintIcon('tabler-question-mark', trans('admin/node.upload_limit_help')) ->columnSpan(1) ->numeric()->required() ->default(256) ->minValue(1) - ->maxValue(1024) ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB'), TextInput::make('daemon_sftp') ->columnSpan(1) diff --git a/app/Filament/Admin/Resources/Nodes/Pages/EditNode.php b/app/Filament/Admin/Resources/Nodes/Pages/EditNode.php index 20cd7036c..0497beae2 100644 --- a/app/Filament/Admin/Resources/Nodes/Pages/EditNode.php +++ b/app/Filament/Admin/Resources/Nodes/Pages/EditNode.php @@ -319,10 +319,10 @@ class EditNode extends EditRecord 'lg' => 1, ]) ->label(trans('admin/node.upload_limit')) - ->hintIcon('tabler-question-mark', trans('admin/node.upload_limit_help.0') . trans('admin/node.upload_limit_help.1')) - ->numeric()->required() + ->hintIcon('tabler-question-mark', trans('admin/node.upload_limit_help')) + ->numeric() + ->required() ->minValue(1) - ->maxValue(1024) ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB'), TextInput::make('daemon_sftp') ->columnSpan([ diff --git a/app/Http/Controllers/Api/Client/Servers/BackupController.php b/app/Http/Controllers/Api/Client/Servers/BackupController.php index fd6217ad6..d5492cbcd 100644 --- a/app/Http/Controllers/Api/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Api/Client/Servers/BackupController.php @@ -83,15 +83,21 @@ class BackupController extends ClientApiController // how best to allow a user to create a backup that is locked without also preventing // them from just filling up a server with backups that can never be deleted? if ($request->user()->can(SubuserPermission::BackupDelete, $server)) { - $action->setIsLocked((bool) $request->input('is_locked')); + $action->setIsLocked($request->boolean('is_locked')); } - $backup = $action->handle($server, $request->input('name')); + $backup = Activity::event('server:backup.start')->transaction(function ($log) use ($action, $server, $request) { + $server->backups()->lockForUpdate(); - Activity::event('server:backup.start') - ->subject($backup) - ->property(['name' => $backup->name, 'locked' => (bool) $request->input('is_locked')]) - ->log(); + $backup = $action->handle($server, $request->input('name')); + + $log->subject($backup)->property([ + 'name' => $backup->name, + 'locked' => $request->boolean('is_locked'), + ]); + + return $backup; + }); return $this->fractal->item($backup) ->transformWith($this->getTransformer(BackupTransformer::class)) diff --git a/app/Http/Controllers/Api/Client/Servers/DatabaseController.php b/app/Http/Controllers/Api/Client/Servers/DatabaseController.php index 2ce65f017..445c8b2bc 100644 --- a/app/Http/Controllers/Api/Client/Servers/DatabaseController.php +++ b/app/Http/Controllers/Api/Client/Servers/DatabaseController.php @@ -59,12 +59,15 @@ class DatabaseController extends ClientApiController */ public function store(StoreDatabaseRequest $request, Server $server): array { - $database = $this->deployDatabaseService->handle($server, $request->validated()); + $database = Activity::event('server:database.create')->transaction(function ($log) use ($request, $server) { + $server->databases()->lockForUpdate(); - Activity::event('server:database.create') - ->subject($database) - ->property('name', $database->database) - ->log(); + $database = $this->deployDatabaseService->handle($server, $request->validated()); + + $log->subject($database)->property('name', $database->database); + + return $database; + }); return $this->fractal->item($database) ->parseIncludes(['password']) diff --git a/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php b/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php index 08bfb54f2..fc8ae338d 100644 --- a/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php +++ b/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php @@ -107,16 +107,19 @@ class NetworkAllocationController extends ClientApiController */ public function store(NewAllocationRequest $request, Server $server): array { - if ($server->allocations()->count() >= $server->allocation_limit) { - throw new DisplayException('Cannot assign additional allocations to this server: limit has been reached.'); - } + $allocation = Activity::event('server:allocation.create')->transaction(function ($log) use ($server) { + $server->allocations()->lockForUpdate(); - $allocation = $this->assignableAllocationService->handle($server); + if ($server->allocations->count() >= $server->allocation_limit) { + throw new DisplayException('Cannot assign additional allocations to this server: limit has been reached.'); + } - Activity::event('server:allocation.create') - ->subject($allocation) - ->property('allocation', $allocation->address) - ->log(); + $allocation = $this->assignableAllocationService->handle($server); + + $log->subject($allocation)->property('allocation', $allocation->address); + + return $allocation; + }); return $this->fractal->item($allocation) ->transformWith($this->getTransformer(AllocationTransformer::class)) diff --git a/app/Http/Controllers/Api/Remote/Backups/BackupRemoteUploadController.php b/app/Http/Controllers/Api/Remote/Backups/BackupRemoteUploadController.php index 77d869949..fa149c31e 100644 --- a/app/Http/Controllers/Api/Remote/Backups/BackupRemoteUploadController.php +++ b/app/Http/Controllers/Api/Remote/Backups/BackupRemoteUploadController.php @@ -131,7 +131,7 @@ class BackupRemoteUploadController extends Controller */ private function getConfiguredMaxPartSize(): int { - $maxPartSize = (int) config('backups.max_part_size', self::DEFAULT_MAX_PART_SIZE); + $maxPartSize = config('backups.max_part_size', self::DEFAULT_MAX_PART_SIZE); if ($maxPartSize <= 0) { $maxPartSize = self::DEFAULT_MAX_PART_SIZE; } diff --git a/app/Models/Node.php b/app/Models/Node.php index 69b1072d5..4c5479dc3 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -110,7 +110,7 @@ class Node extends Model implements Validatable 'daemon_listen' => ['required', 'numeric', 'between:1,65535'], 'daemon_connect' => ['required', 'numeric', 'between:1,65535'], 'maintenance_mode' => ['boolean'], - 'upload_size' => ['int', 'between:1,1024'], + 'upload_size' => ['int', 'min:1'], 'tags' => ['array'], ]; diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 311e3d0fc..36c42d07c 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Enums\ResourceLimit; use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Foundation\Http\Middleware\TrimStrings; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; @@ -98,5 +99,7 @@ class RouteServiceProvider extends ServiceProvider config('http.rate_limit.application') )->by($key); }); + + ResourceLimit::boot(); } } diff --git a/app/Repositories/Daemon/DaemonServerRepository.php b/app/Repositories/Daemon/DaemonServerRepository.php index e4abe7408..6088acf13 100644 --- a/app/Repositories/Daemon/DaemonServerRepository.php +++ b/app/Repositories/Daemon/DaemonServerRepository.php @@ -133,6 +133,9 @@ class DaemonServerRepository extends DaemonRepository * make it easier to revoke tokens on the fly. This ensures that the JTI key is formatted * correctly and avoids any costly mistakes in the codebase. * + * @deprecated + * @see self::deauthorize() + * * @throws ConnectionException */ public function revokeUserJTI(int $id): void @@ -143,6 +146,21 @@ class DaemonServerRepository extends DaemonRepository ]); } + /** + * Deauthorizes a user (disconnects websockets and SFTP) on the Wings instance for the server. + * + * @throws ConnectionException + */ + public function deauthorize(string $user): void + { + $this->getHttpClient()->post('/api/deauthorize-user', [ + 'json' => [ + 'user' => $user, + 'servers' => [$this->server->uuid], + ], + ]); + } + public function getInstallLogs(): string { return $this->getHttpClient() diff --git a/app/Services/Servers/DetailsModificationService.php b/app/Services/Servers/DetailsModificationService.php index b3b789d60..e8c40e3c5 100644 --- a/app/Services/Servers/DetailsModificationService.php +++ b/app/Services/Servers/DetailsModificationService.php @@ -48,7 +48,7 @@ class DetailsModificationService // websockets. if ($server->owner_id !== $owner) { try { - $this->serverRepository->setServer($server)->revokeUserJTI($owner); + $this->serverRepository->setServer($server)->deauthorize($server->user->uuid); } catch (ConnectionException) { // Do nothing. A failure here is not ideal, but it is likely to be caused by daemon // being offline, or in an entirely broken state. Remember, these tokens reset every diff --git a/app/Services/Servers/ServerDeletionService.php b/app/Services/Servers/ServerDeletionService.php index 925694f27..7f59d017c 100644 --- a/app/Services/Servers/ServerDeletionService.php +++ b/app/Services/Servers/ServerDeletionService.php @@ -78,7 +78,10 @@ class ServerDeletionService } } - $server->allocations()->update(['server_id' => null]); + $server->allocations()->update([ + 'server_id' => null, + 'notes' => null, + ]); $server->delete(); }); diff --git a/app/Services/Subusers/SubuserDeletionService.php b/app/Services/Subusers/SubuserDeletionService.php index b68b948f8..bbf232995 100644 --- a/app/Services/Subusers/SubuserDeletionService.php +++ b/app/Services/Subusers/SubuserDeletionService.php @@ -28,7 +28,7 @@ class SubuserDeletionService event(new SubUserRemoved($subuser->server, $subuser->user)); try { - $this->serverRepository->setServer($server)->revokeUserJTI($subuser->user_id); + $this->serverRepository->setServer($server)->deauthorize($subuser->user->uuid); } catch (ConnectionException $exception) { // Don't block this request if we can't connect to the daemon instance. logger()->warning($exception, ['user_id' => $subuser->user_id, 'server_id' => $server->id]); diff --git a/app/Services/Subusers/SubuserUpdateService.php b/app/Services/Subusers/SubuserUpdateService.php index 14fd9decd..1ce9c0ac5 100644 --- a/app/Services/Subusers/SubuserUpdateService.php +++ b/app/Services/Subusers/SubuserUpdateService.php @@ -46,7 +46,7 @@ class SubuserUpdateService $subuser->update(['permissions' => $cleanedPermissions]); try { - $this->serverRepository->setServer($server)->revokeUserJTI($subuser->user_id); + $this->serverRepository->setServer($server)->deauthorize($subuser->user->uuid); } catch (ConnectionException $exception) { // Don't block this request if we can't connect to the daemon instance. Chances are it is // offline and the token will be invalid once daemon boots back. diff --git a/bootstrap/app.php b/bootstrap/app.php index d40ab8cc3..cd5ca7005 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -44,6 +44,10 @@ return Application::configure(basePath: dirname(__DIR__)) 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'node.maintenance' => \App\Http\Middleware\MaintenanceMiddleware::class, ]); + + $middleware->priority([ + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ]); }) ->withSingletons([ \Illuminate\Contracts\Console\Kernel::class => \App\Console\Kernel::class, diff --git a/config/backups.php b/config/backups.php index 0074bf8d7..c3bf16cf7 100644 --- a/config/backups.php +++ b/config/backups.php @@ -1,5 +1,6 @@ env('BACKUP_PRESIGNED_URL_LIFESPAN', 60), + 'presigned_url_lifespan' => (int) env('BACKUP_PRESIGNED_URL_LIFESPAN', 60), // This value defines the maximal size of a single part for the S3 multipart upload during backups // The maximal part size must be given in bytes. The default value is 5GB. // Note that 5GB is the maximum for a single part when using AWS S3. - 'max_part_size' => env('BACKUP_MAX_PART_SIZE', 5 * 1024 * 1024 * 1024), + 'max_part_size' => (int) env('BACKUP_MAX_PART_SIZE', BackupRemoteUploadController::DEFAULT_MAX_PART_SIZE), // The time to wait before automatically failing a backup, time is in minutes and defaults // to 6 hours. To disable this feature, set the value to `0`. - 'prune_age' => env('BACKUP_PRUNE_AGE', 360), + 'prune_age' => (int) env('BACKUP_PRUNE_AGE', 360), // Defines the backup creation throttle limits for users. In this default example, we allow // a user to create two (successful or pending) backups per 10 minutes. Even if they delete @@ -27,8 +28,8 @@ return [ // // Set the period to "0" to disable this throttle. The period is defined in seconds. 'throttles' => [ - 'limit' => env('BACKUP_THROTTLE_LIMIT', 2), - 'period' => env('BACKUP_THROTTLE_PERIOD', 600), + 'limit' => (int) env('BACKUP_THROTTLE_LIMIT', 2), + 'period' => (int) env('BACKUP_THROTTLE_PERIOD', 600), ], 'disks' => [ diff --git a/config/http.php b/config/http.php index ed54e475b..69bf4b530 100644 --- a/config/http.php +++ b/config/http.php @@ -13,7 +13,7 @@ return [ */ 'rate_limit' => [ 'client_period' => 1, - 'client' => env('APP_API_CLIENT_RATELIMIT', 720), + 'client' => env('APP_API_CLIENT_RATELIMIT', 120), 'application_period' => 1, 'application' => env('APP_API_APPLICATION_RATELIMIT', 240), diff --git a/contributing.md b/contributing.md index 70cc654c7..627c04e4c 100644 --- a/contributing.md +++ b/contributing.md @@ -8,7 +8,7 @@ To start contributing to Pelican Panel, you need to have a basic understanding o * [PHP](https://php.net) & [Laravel](https://laravel.com) * [Livewire](https://laravel-livewire.com) & [Filament](https://filamentphp.com) -* [Git](https://git-scm.com) & [Github](https://github.com) +* [Git](https://git-scm.com) & [GitHub](https://github.com) ## Dev Environment Setup diff --git a/database/migrations/2026_01_09_134116_clear_unused_allocation_notes.php b/database/migrations/2026_01_09_134116_clear_unused_allocation_notes.php new file mode 100644 index 000000000..6eb6e5c2d --- /dev/null +++ b/database/migrations/2026_01_09_134116_clear_unused_allocation_notes.php @@ -0,0 +1,25 @@ +whereNull('server_id') + ->update(['notes' => null]); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // Not needed + } +}; diff --git a/lang/en/admin/node.php b/lang/en/admin/node.php index 40b514673..32b3fdd32 100644 --- a/lang/en/admin/node.php +++ b/lang/en/admin/node.php @@ -61,10 +61,7 @@ return [ 'tags' => 'Tags', 'upload_limit' => 'Upload Limit', - 'upload_limit_help' => [ - 'Enter the maximum size of files that can be uploaded through the web-based file manager.', - 'Make sure your webserver supports file uploads of this size!', - ], + 'upload_limit_help' => 'Enter the maximum size of files that can be uploaded through the web-based file manager.', 'sftp_port' => 'SFTP Port', 'sftp_alias' => 'SFTP Alias', 'sftp_alias_help' => 'Display alias for the SFTP address. Leave empty to use the Node FQDN.', diff --git a/routes/api-client.php b/routes/api-client.php index 12ab28af7..4365cfeb2 100644 --- a/routes/api-client.php +++ b/routes/api-client.php @@ -1,5 +1,6 @@ middleware(AccountSubject::class)->group(function () */ Route::prefix('/servers/{server:uuid}')->middleware([ServerSubject::class, AuthenticateServerAccess::class, ResourceBelongsToServer::class])->group(function () { Route::get('/', [Client\Servers\ServerController::class, 'index'])->name('api:client:server.view'); - Route::get('/websocket', Client\Servers\WebsocketController::class)->name('api:client:server.ws'); + Route::middleware([ResourceLimit::Websocket->middleware()]) + ->get('/websocket', Client\Servers\WebsocketController::class) + ->name('api:client:server.ws'); Route::get('/resources', Client\Servers\ResourceUtilizationController::class)->name('api:client:server.resources'); Route::get('/activity', Client\Servers\ActivityLogController::class)->name('api:client:server.activity'); @@ -59,7 +62,8 @@ Route::prefix('/servers/{server:uuid}')->middleware([ServerSubject::class, Authe Route::prefix('/databases')->group(function () { Route::get('/', [Client\Servers\DatabaseController::class, 'index']); - Route::post('/', [Client\Servers\DatabaseController::class, 'store']); + Route::middleware([ResourceLimit::DatabaseCreate->middleware()]) + ->post('/', [Client\Servers\DatabaseController::class, 'store']); Route::post('/{database}/rotate-password', [Client\Servers\DatabaseController::class, 'rotatePassword']); Route::delete('/{database}', [Client\Servers\DatabaseController::class, 'delete']); }); @@ -76,13 +80,15 @@ Route::prefix('/servers/{server:uuid}')->middleware([ServerSubject::class, Authe Route::post('/delete', [Client\Servers\FileController::class, 'delete']); Route::post('/create-folder', [Client\Servers\FileController::class, 'create']); Route::post('/chmod', [Client\Servers\FileController::class, 'chmod']); - Route::post('/pull', [Client\Servers\FileController::class, 'pull'])->middleware(['throttle:10,5']); + Route::middleware([ResourceLimit::FilePull->middleware()]) + ->post('/pull', [Client\Servers\FileController::class, 'pull']); Route::get('/upload', Client\Servers\FileUploadController::class); }); Route::prefix('/schedules')->group(function () { Route::get('/', [Client\Servers\ScheduleController::class, 'index']); - Route::post('/', [Client\Servers\ScheduleController::class, 'store']); + Route::middleware([ResourceLimit::ScheduleCreate->middleware()]) + ->post('/', [Client\Servers\ScheduleController::class, 'store']); Route::get('/{schedule}', [Client\Servers\ScheduleController::class, 'view']); Route::post('/{schedule}', [Client\Servers\ScheduleController::class, 'update']); Route::post('/{schedule}/execute', [Client\Servers\ScheduleController::class, 'execute']); @@ -95,7 +101,8 @@ Route::prefix('/servers/{server:uuid}')->middleware([ServerSubject::class, Authe Route::prefix('/network/allocations')->group(function () { Route::get('/', [Client\Servers\NetworkAllocationController::class, 'index']); - Route::post('/', [Client\Servers\NetworkAllocationController::class, 'store']); + Route::middleware([ResourceLimit::AllocationCreate->middleware()]) + ->post('/', [Client\Servers\NetworkAllocationController::class, 'store']); Route::post('/{allocation}', [Client\Servers\NetworkAllocationController::class, 'update']); Route::post('/{allocation}/primary', [Client\Servers\NetworkAllocationController::class, 'setPrimary']); Route::delete('/{allocation}', [Client\Servers\NetworkAllocationController::class, 'delete']); @@ -103,7 +110,8 @@ Route::prefix('/servers/{server:uuid}')->middleware([ServerSubject::class, Authe Route::prefix('/users')->group(function () { Route::get('/', [Client\Servers\SubuserController::class, 'index']); - Route::post('/', [Client\Servers\SubuserController::class, 'store']); + Route::middleware([ResourceLimit::SubuserCreate->middleware()]) + ->post('/', [Client\Servers\SubuserController::class, 'store']); Route::get('/{user:uuid}', [Client\Servers\SubuserController::class, 'view']); Route::post('/{user:uuid}', [Client\Servers\SubuserController::class, 'update']); Route::delete('/{user:uuid}', [Client\Servers\SubuserController::class, 'delete']); @@ -116,7 +124,8 @@ Route::prefix('/servers/{server:uuid}')->middleware([ServerSubject::class, Authe Route::get('/{backup:uuid}/download', [Client\Servers\BackupController::class, 'download']); Route::put('/{backup:uuid}/rename', [Client\Servers\BackupController::class, 'rename']); Route::post('/{backup:uuid}/lock', [Client\Servers\BackupController::class, 'toggleLock']); - Route::post('/{backup:uuid}/restore', [Client\Servers\BackupController::class, 'restore']); + Route::middleware([ResourceLimit::BackupRestore->middleware()]) + ->post('/{backup:uuid}/restore', [Client\Servers\BackupController::class, 'restore']); Route::delete('/{backup:uuid}', [Client\Servers\BackupController::class, 'delete']); }); diff --git a/security.md b/security.md index 093456c58..520e6e2d6 100644 --- a/security.md +++ b/security.md @@ -8,8 +8,9 @@ While Pelican is in beta, we only provide security fixes for the most recent bet ## Reporting a Vulnerability Please report any vulnerabilities via _one_ of the following methods: -- [Create a security advisory on Github](https://github.com/pelican-dev/panel/security/advisories/new) -- Send an e-mail to team@pelican.dev + +- [Create a security advisory on GitHub](https://github.com/pelican-dev/panel/security/advisories/new) +- Send an e-mail to Include steps to reproduce, affected versions, impact, and a proof of concept if available. diff --git a/tests/Integration/Api/Client/Server/Subuser/DeleteSubuserTest.php b/tests/Integration/Api/Client/Server/Subuser/DeleteSubuserTest.php index 63440a084..f0a368c25 100644 --- a/tests/Integration/Api/Client/Server/Subuser/DeleteSubuserTest.php +++ b/tests/Integration/Api/Client/Server/Subuser/DeleteSubuserTest.php @@ -42,7 +42,7 @@ class DeleteSubuserTest extends ClientApiIntegrationTestCase 'permissions' => [SubuserPermission::WebsocketConnect], ]); - $mock->expects('setServer->revokeUserJTI')->with($subuser->id)->andReturnUndefined(); + $mock->expects('setServer->deauthorize')->with($subuser->uuid)->andReturnUndefined(); $this->actingAs($user)->deleteJson($this->link($server) . "/users/$subuser->uuid")->assertNoContent(); @@ -58,7 +58,7 @@ class DeleteSubuserTest extends ClientApiIntegrationTestCase 'permissions' => [SubuserPermission::WebsocketConnect], ]); - $mock->expects('setServer->revokeUserJTI')->with($subuser->id)->andReturnUndefined(); + $mock->expects('setServer->deauthorize')->with($subuser->uuid)->andReturnUndefined(); $this->actingAs($user)->deleteJson($this->link($server) . "/users/$subuser->uuid")->assertNoContent(); } diff --git a/tests/Integration/Api/Client/Server/Subuser/SubuserAuthorizationTest.php b/tests/Integration/Api/Client/Server/Subuser/SubuserAuthorizationTest.php index 31370dcc7..b838c9778 100644 --- a/tests/Integration/Api/Client/Server/Subuser/SubuserAuthorizationTest.php +++ b/tests/Integration/Api/Client/Server/Subuser/SubuserAuthorizationTest.php @@ -37,7 +37,7 @@ class SubuserAuthorizationTest extends ClientApiIntegrationTestCase $this->instance(DaemonServerRepository::class, $mock = \Mockery::mock(DaemonServerRepository::class)); if ($method === 'DELETE') { - $mock->expects('setServer->revokeUserJTI')->with($internal->id)->andReturnUndefined(); + $mock->expects('setServer->deauthorize')->with($internal->uuid)->andReturnUndefined(); } // This route is acceptable since they're accessing a subuser on their own server.