├── app ├── Policies │ └── .gitkeep ├── Events │ ├── Event.php │ ├── Auth │ │ └── ProvidedAuthenticationToken.php │ ├── Server │ │ ├── Installed.php │ │ ├── Saved.php │ │ ├── Saving.php │ │ ├── Created.php │ │ ├── Creating.php │ │ ├── Deleted.php │ │ ├── Deleting.php │ │ ├── Updated.php │ │ └── Updating.php │ ├── User │ │ ├── Created.php │ │ ├── Creating.php │ │ ├── Deleted.php │ │ └── Deleting.php │ └── Subuser │ │ ├── Created.php │ │ ├── Deleted.php │ │ └── Creating.php ├── Exceptions │ ├── PterodactylException.php │ ├── Repository │ │ ├── RepositoryException.php │ │ ├── DuplicateDatabaseNameException.php │ │ ├── Daemon │ │ │ └── InvalidPowerSignalException.php │ │ └── RecordNotFoundException.php │ ├── Service │ │ ├── Egg │ │ │ ├── BadJsonFormatException.php │ │ │ ├── Variable │ │ │ │ ├── BadValidationRuleException.php │ │ │ │ └── ReservedVariableNameException.php │ │ │ ├── HasChildrenException.php │ │ │ ├── InvalidCopyFromException.php │ │ │ └── NoParentConfigurationFoundException.php │ │ ├── Deployment │ │ │ ├── NoViableNodeException.php │ │ │ └── NoViableAllocationException.php │ │ ├── Node │ │ │ └── ConfigurationNotPersistedException.php │ │ ├── Allocation │ │ │ ├── ServerUsingAllocationException.php │ │ │ ├── AllocationDoesNotBelongToServerException.php │ │ │ ├── CidrOutOfRangeException.php │ │ │ ├── PortOutOfRangeException.php │ │ │ ├── TooManyPortsInRangeException.php │ │ │ ├── AutoAllocationNotEnabledException.php │ │ │ ├── InvalidPortMappingException.php │ │ │ └── NoAutoAllocationSpaceAvailableException.php │ │ ├── HasActiveServersException.php │ │ ├── Database │ │ │ ├── TooManyDatabasesException.php │ │ │ ├── DatabaseClientFeatureNotEnabledException.php │ │ │ └── NoSuitableDatabaseHostException.php │ │ ├── Location │ │ │ └── HasActiveNodesException.php │ │ ├── Helper │ │ │ └── CdnVersionFetchingException.php │ │ ├── Backup │ │ │ ├── BackupLockedException.php │ │ │ └── TooManyBackupsException.php │ │ ├── InvalidFileUploadException.php │ │ ├── Subuser │ │ │ ├── UserIsServerOwnerException.php │ │ │ └── ServerSubuserExistsException.php │ │ ├── Schedule │ │ │ └── Task │ │ │ │ └── TaskIntervalTooLongException.php │ │ ├── Server │ │ │ └── RequiredVariableMissingException.php │ │ ├── User │ │ │ └── TwoFactorAuthenticationTokenInvalid.php │ │ └── ServiceLimitExceededException.php │ ├── Transformer │ │ └── InvalidTransformerLevelException.php │ ├── AutoDeploymentException.php │ ├── AccountNotFoundException.php │ └── Http │ │ ├── Server │ │ ├── FileTypeNotEditableException.php │ │ └── FileSizeTooLargeException.php │ │ ├── Base │ │ └── InvalidPasswordProvidedException.php │ │ ├── HttpForbiddenException.php │ │ └── TwoFactorAuthRequiredException.php ├── Contracts │ ├── Repository │ │ ├── UserRepositoryInterface.php │ │ ├── ServerVariableRepositoryInterface.php │ │ ├── PermissionRepositoryInterface.php │ │ ├── ApiPermissionRepositoryInterface.php │ │ ├── DatabaseHostRepositoryInterface.php │ │ ├── SessionRepositoryInterface.php │ │ ├── AllocationRepositoryInterface.php │ │ ├── TaskRepositoryInterface.php │ │ ├── ScheduleRepositoryInterface.php │ │ └── EggVariableRepositoryInterface.php │ ├── Core │ │ └── ReceivesEvents.php │ ├── Http │ │ └── ClientPermissionsRequest.php │ ├── Criteria │ │ └── CriteriaInterface.php │ └── Extensions │ │ └── HashidsInterface.php ├── Http │ ├── Requests │ │ ├── Api │ │ │ ├── Application │ │ │ │ ├── Nodes │ │ │ │ │ ├── GetNodeRequest.php │ │ │ │ │ ├── GetNodesRequest.php │ │ │ │ │ ├── DeleteNodeRequest.php │ │ │ │ │ ├── GetDeployableNodesRequest.php │ │ │ │ │ └── UpdateNodeRequest.php │ │ │ │ ├── Locations │ │ │ │ │ ├── GetLocationRequest.php │ │ │ │ │ ├── GetLocationsRequest.php │ │ │ │ │ ├── DeleteLocationRequest.php │ │ │ │ │ └── UpdateLocationRequest.php │ │ │ │ ├── Servers │ │ │ │ │ ├── GetServersRequest.php │ │ │ │ │ ├── Databases │ │ │ │ │ │ ├── ServerDatabaseWriteRequest.php │ │ │ │ │ │ ├── GetServerDatabaseRequest.php │ │ │ │ │ │ └── GetServerDatabasesRequest.php │ │ │ │ │ ├── GetServerRequest.php │ │ │ │ │ ├── ServerWriteRequest.php │ │ │ │ │ └── GetExternalServerRequest.php │ │ │ │ ├── Users │ │ │ │ │ ├── GetUsersRequest.php │ │ │ │ │ ├── DeleteUserRequest.php │ │ │ │ │ ├── UpdateUserRequest.php │ │ │ │ │ └── GetExternalUserRequest.php │ │ │ │ ├── Nests │ │ │ │ │ ├── GetNestsRequest.php │ │ │ │ │ └── Eggs │ │ │ │ │ │ ├── GetEggRequest.php │ │ │ │ │ │ └── GetEggsRequest.php │ │ │ │ └── Allocations │ │ │ │ │ ├── GetAllocationsRequest.php │ │ │ │ │ └── DeleteAllocationRequest.php │ │ │ ├── Client │ │ │ │ ├── GetServersRequest.php │ │ │ │ └── Servers │ │ │ │ │ ├── Network │ │ │ │ │ ├── SetPrimaryAllocationRequest.php │ │ │ │ │ ├── NewAllocationRequest.php │ │ │ │ │ ├── DeleteAllocationRequest.php │ │ │ │ │ ├── GetNetworkRequest.php │ │ │ │ │ └── UpdateAllocationRequest.php │ │ │ │ │ ├── Schedules │ │ │ │ │ ├── DeleteScheduleRequest.php │ │ │ │ │ ├── UpdateScheduleRequest.php │ │ │ │ │ └── TriggerScheduleRequest.php │ │ │ │ │ ├── Subusers │ │ │ │ │ ├── DeleteSubuserRequest.php │ │ │ │ │ ├── GetSubuserRequest.php │ │ │ │ │ ├── UpdateSubuserRequest.php │ │ │ │ │ └── StoreSubuserRequest.php │ │ │ │ │ ├── Files │ │ │ │ │ ├── UploadFileRequest.php │ │ │ │ │ ├── DownloadFileRequest.php │ │ │ │ │ ├── CopyFileRequest.php │ │ │ │ │ ├── CreateFolderRequest.php │ │ │ │ │ ├── ListFilesRequest.php │ │ │ │ │ ├── DeleteFileRequest.php │ │ │ │ │ └── CompressFilesRequest.php │ │ │ │ │ ├── Startup │ │ │ │ │ └── GetStartupRequest.php │ │ │ │ │ ├── Settings │ │ │ │ │ └── ReinstallServerRequest.php │ │ │ │ │ ├── Databases │ │ │ │ │ ├── GetDatabasesRequest.php │ │ │ │ │ ├── DeleteDatabaseRequest.php │ │ │ │ │ └── RotatePasswordRequest.php │ │ │ │ │ ├── GetServerRequest.php │ │ │ │ │ ├── Backups │ │ │ │ │ └── StoreBackupRequest.php │ │ │ │ │ └── SendCommandRequest.php │ │ │ └── Remote │ │ │ │ ├── InstallationDataRequest.php │ │ │ │ ├── AuthenticateWebsocketDetailsRequest.php │ │ │ │ └── ReportBackupCompleteRequest.php │ │ ├── Auth │ │ │ ├── LoginRequest.php │ │ │ └── ResetPasswordRequest.php │ │ └── Admin │ │ │ ├── BaseFormRequest.php │ │ │ ├── MountFormRequest.php │ │ │ ├── Nest │ │ │ └── StoreNestFormRequest.php │ │ │ ├── Node │ │ │ └── AllocationAliasFormRequest.php │ │ │ └── UserFormRequest.php │ ├── Middleware │ │ ├── EncryptCookies.php │ │ ├── TrimStrings.php │ │ ├── VerifyCsrfToken.php │ │ └── Activity │ │ │ └── AccountSubject.php │ └── Controllers │ │ └── Controller.php ├── Services │ └── Helpers │ │ └── ApiAllowedIpsValidatorService.php ├── Extensions │ ├── Illuminate │ │ ├── Events │ │ │ └── Contracts │ │ │ │ └── SubscribesToEvents.php │ │ └── Database │ │ │ └── Eloquent │ │ │ └── Builder.php │ ├── Facades │ │ └── Theme.php │ ├── Themes │ │ └── Theme.php │ └── Laravel │ │ └── Sanctum │ │ └── NewAccessToken.php ├── Facades │ ├── Activity.php │ ├── LogBatch.php │ └── LogTarget.php ├── Repositories │ └── Eloquent │ │ ├── RecoveryTokenRepository.php │ │ ├── UserRepository.php │ │ ├── ServerVariableRepository.php │ │ └── PermissionRepository.php ├── Models │ ├── EggMount.php │ ├── MountNode.php │ ├── Session.php │ ├── MountServer.php │ └── Setting.php ├── Traits │ └── Controllers │ │ └── PlainJavascriptInjection.php ├── Providers │ ├── ViewComposerServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── ActivityLogServiceProvider.php │ ├── BladeServiceProvider.php │ └── BackupsServiceProvider.php ├── Listeners │ └── Auth │ │ ├── TwoFactorListener.php │ │ └── PasswordResetListener.php ├── Observers │ └── EggVariableObserver.php ├── Transformers │ └── Api │ │ ├── Application │ │ └── EggVariableTransformer.php │ │ └── Client │ │ ├── EggTransformer.php │ │ └── UserSSHKeyTransformer.php ├── Jobs │ └── Job.php └── Console │ └── Commands │ └── Overrides │ ├── UpCommand.php │ └── SeedCommand.php ├── database ├── Seeders │ ├── .gitkeep │ └── DatabaseSeeder.php ├── .gitignore ├── migrations │ ├── 2017_09_10_225749_RenameTasksTableForStructureRefactor.php │ ├── 2016_10_23_181719_update_misnamed_bungee.php │ ├── 2016_01_23_203119_create_settings_table.php │ ├── 2016_01_25_234418_rename_permissions_column.php │ ├── 2016_03_18_155649_add_nullable_field_lastrun.php │ ├── 2016_01_23_200044_add_api_permissions.php │ ├── 2016_01_23_200528_add_locations.php │ ├── 2016_01_23_201433_add_password_resets.php │ ├── 2016_02_20_155318_add_unique_service_field.php │ ├── 2016_09_01_211924_remove_active_column.php │ ├── 2016_09_29_213518_rename_double_insurgency.php │ ├── 2022_01_25_030847_drop_google_analytics.php │ ├── 2016_09_02_190647_add_sftp_password_storage.php │ ├── 2017_07_24_194433_DeleteTaskWhenParentServerIsDeleted.php │ ├── 2016_09_01_193520_add_suspension_for_servers.php │ ├── 2016_09_04_172028_update_failed_jobs_table.php │ ├── 2016_09_07_163017_add_unique_identifier.php │ ├── 2016_11_11_231731_set_service_name_unique.php │ ├── 2016_10_23_204610_add_foreign_tasks.php │ ├── 2016_01_23_195851_add_api_keys.php │ ├── 2016_01_23_200159_add_downloads.php │ ├── 2016_09_14_145945_allow_longer_regex_field.php │ ├── 2017_03_14_200326_AddLockedStatusToTable.php │ ├── 2017_03_18_204953_AddForeignKeyToPacks.php │ ├── 2017_03_31_221948_AddServerDescriptionColumn.php │ ├── 2017_04_02_163232_DropDeletedAtColumnFromServers.php │ ├── 2016_09_21_165554_update_servers_column_name.php │ └── 2017_06_10_152951_add_external_id_to_users.php └── Factories │ ├── TaskFactory.php │ ├── ScheduleFactory.php │ ├── LocationFactory.php │ ├── SubuserFactory.php │ └── NestFactory.php ├── bootstrap └── cache │ └── .gitignore ├── storage ├── debugbar │ └── .gitignore ├── logs │ └── .gitignore ├── clockwork │ └── .gitignore ├── framework │ ├── cache │ │ ├── data │ │ │ └── .gitignore │ │ └── .gitignore │ ├── views │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ └── .gitignore └── app │ └── .gitignore ├── public ├── robots.txt ├── .gitignore ├── favicons │ ├── favicon.ico │ ├── apple-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── ms-icon-70x70.png │ ├── mstile-150x150.png │ ├── apple-icon-57x57.png │ ├── apple-icon-60x60.png │ ├── apple-icon-72x72.png │ ├── apple-icon-76x76.png │ ├── apple-touch-icon.png │ ├── ms-icon-144x144.png │ ├── ms-icon-150x150.png │ ├── ms-icon-310x310.png │ ├── android-icon-36x36.png │ ├── android-icon-48x48.png │ ├── android-icon-72x72.png │ ├── android-icon-96x96.png │ ├── apple-icon-114x114.png │ ├── apple-icon-120x120.png │ ├── apple-icon-144x144.png │ ├── apple-icon-152x152.png │ ├── apple-icon-180x180.png │ ├── android-icon-144x144.png │ ├── android-icon-192x192.png │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-icon-precomposed.png │ ├── df4b367461890fa5fd0d9339d3c3f9c6.ico.zip │ └── browserconfig.xml ├── themes │ └── pterodactyl │ │ └── vendor │ │ └── ace │ │ ├── ext-error_marker.js │ │ └── mode-plain_text.js ├── js │ └── autocomplete.js └── .htaccess ├── resources ├── scripts │ ├── setup-tests.ts │ ├── __mocks__ │ │ └── file.ts │ ├── components │ │ ├── elements │ │ │ ├── alert │ │ │ │ └── index.ts │ │ │ ├── button │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── dropdown │ │ │ │ └── index.ts │ │ │ ├── transitions │ │ │ │ └── index.ts │ │ │ ├── Portal.tsx │ │ │ ├── Label.tsx │ │ │ ├── inputs │ │ │ │ ├── index.ts │ │ │ │ └── Checkbox.tsx │ │ │ ├── Translate.tsx │ │ │ ├── ContentContainer.tsx │ │ │ ├── activity │ │ │ │ └── style.module.css │ │ │ ├── dialog │ │ │ │ ├── context.ts │ │ │ │ ├── index.ts │ │ │ │ └── DialogFooter.tsx │ │ │ ├── GreyRowBox.tsx │ │ │ ├── AuthenticatedRoute.tsx │ │ │ ├── Code.tsx │ │ │ ├── ServerContentBlock.tsx │ │ │ └── Can.tsx │ │ ├── types.ts │ │ ├── history.ts │ │ └── server │ │ │ ├── users │ │ │ └── AddSubuserButton.tsx │ │ │ ├── UptimeDuration.tsx │ │ │ ├── events.ts │ │ │ └── schedules │ │ │ └── NewTaskButton.tsx │ ├── assets │ │ └── tailwind.css │ ├── globals.d.ts │ ├── api │ │ ├── definitions │ │ │ └── user │ │ │ │ └── index.ts │ │ ├── server │ │ │ ├── schedules │ │ │ │ ├── triggerScheduleExecution.ts │ │ │ │ ├── deleteSchedule.ts │ │ │ │ ├── deleteScheduleTask.ts │ │ │ │ └── getServerSchedule.ts │ │ │ ├── setSelectedDockerImage.ts │ │ │ ├── network │ │ │ │ ├── deleteServerAllocation.ts │ │ │ │ ├── createServerAllocation.ts │ │ │ │ ├── setPrimaryServerAllocation.ts │ │ │ │ └── setServerAllocationNotes.ts │ │ │ ├── backups │ │ │ │ ├── index.ts │ │ │ │ ├── deleteBackup.ts │ │ │ │ ├── getBackupDownloadUrl.ts │ │ │ │ └── createServerBackup.ts │ │ │ ├── reinstallServer.ts │ │ │ ├── renameServer.ts │ │ │ ├── users │ │ │ │ ├── deleteSubuser.ts │ │ │ │ └── createOrUpdateSubuser.ts │ │ │ ├── files │ │ │ │ ├── copyFile.ts │ │ │ │ ├── getFileUploadUrl.ts │ │ │ │ ├── saveFileContents.ts │ │ │ │ ├── createDirectory.ts │ │ │ │ ├── deleteFiles.ts │ │ │ │ ├── getFileDownloadUrl.ts │ │ │ │ ├── chmodFiles.ts │ │ │ │ ├── renameFiles.ts │ │ │ │ ├── getFileContents.ts │ │ │ │ ├── decompressFiles.ts │ │ │ │ └── compressFiles.ts │ │ │ ├── databases │ │ │ │ ├── deleteServerDatabase.ts │ │ │ │ └── rotateDatabasePassword.ts │ │ │ ├── updateStartupVariable.ts │ │ │ ├── getWebsocketToken.ts │ │ │ └── types.d.ts │ │ ├── account │ │ │ ├── enableAccountTwoFactor.ts │ │ │ ├── deleteApiKey.ts │ │ │ ├── disableAccountTwoFactor.ts │ │ │ ├── updateAccountEmail.ts │ │ │ ├── getTwoFactorTokenData.ts │ │ │ └── updateAccountPassword.ts │ │ ├── getSystemPermissions.ts │ │ ├── auth │ │ │ └── requestPasswordResetEmail.ts │ │ └── swr │ │ │ └── getServerAllocations.ts │ ├── lib │ │ ├── strings.ts │ │ ├── strings.spec.ts │ │ └── helpers.ts │ ├── plugins │ │ ├── useDeepCompareMemo.ts │ │ ├── useDeepCompareEffect.ts │ │ ├── useDeepMemoize.ts │ │ └── useUserSWRContentKey.ts │ ├── theme.ts │ ├── state │ │ ├── hooks.ts │ │ ├── settings.ts │ │ ├── server │ │ │ └── socket.ts │ │ └── index.ts │ ├── easy-peasy.d.ts │ ├── index.tsx │ ├── context │ │ └── ModalContext.ts │ └── hoc │ │ └── RequireServerPermission.tsx ├── views │ ├── layouts │ │ └── scripts.blade.php │ ├── templates │ │ ├── auth │ │ │ └── core.blade.php │ │ └── base │ │ │ └── core.blade.php │ ├── partials │ │ └── admin │ │ │ └── settings │ │ │ └── notice.blade.php │ └── vendor │ │ └── notifications │ │ └── email-plain.blade.php └── lang │ └── en │ ├── dashboard │ └── index.php │ └── admin │ └── user.php ├── .eslintignore ├── tests ├── CreatesApplication.php └── Unit │ └── Http │ └── Middleware │ └── MiddlewareTestCase.php ├── config ├── activity.php ├── hashids.php ├── egg_features │ └── eula.php └── http.php ├── server.php ├── postcss.config.js ├── routes └── base.php └── .github └── workflows └── buildtest.yml /app/Policies/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/Seeders/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /storage/clockwork/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /public/.gitignore: -------------------------------------------------------------------------------- 1 | assets/* 2 | !assets/svgs 3 | !assets/svgs/*.svg 4 | -------------------------------------------------------------------------------- /resources/scripts/setup-tests.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | -------------------------------------------------------------------------------- /resources/scripts/__mocks__/file.ts: -------------------------------------------------------------------------------- 1 | module.exports = 'test-file-stub'; 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | public 2 | node_modules 3 | resources/views 4 | webpack.config.js 5 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/alert/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Alert } from './Alert'; 2 | -------------------------------------------------------------------------------- /resources/scripts/assets/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /resources/scripts/components/types.ts: -------------------------------------------------------------------------------- 1 | export interface WithClassname { 2 | className?: string; 3 | } 4 | -------------------------------------------------------------------------------- /app/Events/Event.php: -------------------------------------------------------------------------------- 1 | ['body' => 'bg-neutral-900'] 3 | ]) 4 | 5 | @section('container') 6 |
7 | @endsection 8 | -------------------------------------------------------------------------------- /app/Contracts/Repository/ServerVariableRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | ['body' => 'bg-neutral-800'], 3 | ]) 4 | 5 | @section('container') 6 | 7 |
8 | @endsection 9 | -------------------------------------------------------------------------------- /app/Exceptions/Repository/RepositoryException.php: -------------------------------------------------------------------------------- 1 | => 4 | await http.post(`/api/client/servers/${server}/schedules/${schedule}/execute`); 5 | -------------------------------------------------------------------------------- /resources/scripts/api/server/setSelectedDockerImage.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default async (uuid: string, image: string): Promise => { 4 | await http.put(`/api/client/servers/${uuid}/settings/docker-image`, { docker_image: image }); 5 | }; 6 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Deployment/NoViableAllocationException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Allocation/AllocationDoesNotBelongToServerException.php: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /app/Extensions/Illuminate/Events/Contracts/SubscribesToEvents.php: -------------------------------------------------------------------------------- 1 | => 5 | await http.delete(`/api/client/servers/${uuid}/network/allocations/${id}`); 6 | -------------------------------------------------------------------------------- /resources/scripts/plugins/useDeepCompareMemo.ts: -------------------------------------------------------------------------------- 1 | import { DependencyList, useMemo } from 'react'; 2 | import { useDeepMemoize } from '@/plugins/useDeepMemoize'; 3 | 4 | export const useDeepCompareMemo = (callback: () => T, dependencies: DependencyList) => 5 | useMemo(callback, useDeepMemoize(dependencies)); 6 | -------------------------------------------------------------------------------- /resources/scripts/api/account/enableAccountTwoFactor.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default async (code: string, password: string): Promise => { 4 | const { data } = await http.post('/api/client/account/two-factor', { code, password }); 5 | 6 | return data.attributes.tokens; 7 | }; 8 | -------------------------------------------------------------------------------- /resources/scripts/api/server/backups/index.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export const restoreServerBackup = async (uuid: string, backup: string, truncate?: boolean): Promise => { 4 | await http.post(`/api/client/servers/${uuid}/backups/${backup}/restore`, { 5 | truncate, 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /app/Contracts/Core/ReceivesEvents.php: -------------------------------------------------------------------------------- 1 | 5 | useEffect(callback, useDeepMemoize(dependencies)); 6 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/transitions/index.ts: -------------------------------------------------------------------------------- 1 | import { Transition as TransitionComponent } from '@headlessui/react'; 2 | import FadeTransition from '@/components/elements/transitions/FadeTransition'; 3 | 4 | const Transition = Object.assign(TransitionComponent, { 5 | Fade: FadeTransition, 6 | }); 7 | 8 | export { Transition }; 9 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/Portal.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef } from 'react'; 2 | import { createPortal } from 'react-dom'; 3 | 4 | export default ({ children }: { children: React.ReactNode }) => { 5 | const element = useRef(document.getElementById('modal-portal')); 6 | 7 | return createPortal(children, element!.current!); 8 | }; 9 | -------------------------------------------------------------------------------- /resources/scripts/api/server/reinstallServer.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.post(`/api/client/servers/${uuid}/settings/reinstall`) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /app/Facades/Activity.php: -------------------------------------------------------------------------------- 1 | 'string|max:100', 11 | ]; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /resources/scripts/api/account/deleteApiKey.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (identifier: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.delete(`/api/client/account/api-keys/${identifier}`) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /app/Extensions/Facades/Theme.php: -------------------------------------------------------------------------------- 1 | ` 5 | ${tw`block text-xs uppercase text-neutral-200 mb-1 sm:mb-2`}; 6 | ${(props) => props.isLight && tw`text-neutral-700`}; 7 | `; 8 | 9 | export default Label; 10 | -------------------------------------------------------------------------------- /app/Facades/LogBatch.php: -------------------------------------------------------------------------------- 1 | = createBreakpoint({ 5 | xs: 0, 6 | sm: 640, 7 | md: 768, 8 | lg: 1024, 9 | xl: 1280, 10 | }); 11 | -------------------------------------------------------------------------------- /resources/scripts/api/server/renameServer.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, name: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.post(`/api/client/servers/${uuid}/settings/rename`, { name }) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/server/users/deleteSubuser.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, userId: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.delete(`/api/client/servers/${uuid}/users/${userId}`) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /app/Facades/LogTarget.php: -------------------------------------------------------------------------------- 1 | => { 4 | return new Promise((resolve, reject) => { 5 | http.delete('/api/client/account/two-factor', { params: { password } }) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/account/updateAccountEmail.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (email: string, password: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.put('/api/client/account/email', { email, password }) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/server/backups/deleteBackup.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, backup: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.delete(`/api/client/servers/${uuid}/backups/${backup}`) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/server/files/copyFile.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, location: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.post(`/api/client/servers/${uuid}/files/copy`, { location }) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/server/files/getFileUploadUrl.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.get(`/api/client/servers/${uuid}/files/upload`) 6 | .then(({ data }) => resolve(data.attributes.url)) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /database/Seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(NestSeeder::class); 15 | $this->call(EggSeeder::class); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /resources/scripts/api/server/schedules/deleteSchedule.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, schedule: number): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.delete(`/api/client/servers/${uuid}/schedules/${schedule}`) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /app/Repositories/Eloquent/RecoveryTokenRepository.php: -------------------------------------------------------------------------------- 1 | => { 4 | return new Promise((resolve, reject) => { 5 | http.delete(`/api/client/servers/${uuid}/databases/${database}`) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | => { 4 | await http.post(`/api/client/servers/${uuid}/files/write`, content, { 5 | params: { file }, 6 | headers: { 7 | 'Content-Type': 'text/plain', 8 | }, 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Schedules/DeleteScheduleRequest.php: -------------------------------------------------------------------------------- 1 | => { 4 | return new Promise((resolve, reject) => { 5 | http.post(`/api/client/servers/${uuid}/files/create-folder`, { root, name }) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Servers/Databases/ServerDatabaseWriteRequest.php: -------------------------------------------------------------------------------- 1 | => { 4 | return new Promise((resolve, reject) => { 5 | http.post(`/api/client/servers/${uuid}/files/delete`, { root: directory, files }) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/server/backups/getBackupDownloadUrl.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, backup: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.get(`/api/client/servers/${uuid}/backups/${backup}/download`) 6 | .then(({ data }) => resolve(data.attributes.url)) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/getSystemPermissions.ts: -------------------------------------------------------------------------------- 1 | import { PanelPermissions } from '@/state/permissions'; 2 | import http from '@/api/http'; 3 | 4 | export default (): Promise => { 5 | return new Promise((resolve, reject) => { 6 | http.get('/api/client/permissions') 7 | .then(({ data }) => resolve(data.attributes.permissions)) 8 | .catch(reject); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /resources/scripts/api/server/files/getFileDownloadUrl.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, file: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.get(`/api/client/servers/${uuid}/files/download`, { params: { file } }) 6 | .then(({ data }) => resolve(data.attributes.url)) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/inputs/index.ts: -------------------------------------------------------------------------------- 1 | import Checkbox from '@/components/elements/inputs/Checkbox'; 2 | import InputField from '@/components/elements/inputs/InputField'; 3 | 4 | const Input = Object.assign( 5 | {}, 6 | { 7 | Text: InputField, 8 | Checkbox: Checkbox, 9 | } 10 | ); 11 | 12 | export { Input }; 13 | export { default as styles } from './styles.module.css'; 14 | -------------------------------------------------------------------------------- /resources/scripts/state/hooks.ts: -------------------------------------------------------------------------------- 1 | import { createTypedHooks } from 'easy-peasy'; 2 | import { ApplicationStore } from '@/state/index'; 3 | 4 | const hooks = createTypedHooks(); 5 | 6 | export const useStore = hooks.useStore; 7 | export const useStoreState = hooks.useStoreState; 8 | export const useStoreActions = hooks.useStoreActions; 9 | export const useStoreDispatch = hooks.useStoreDispatch; 10 | -------------------------------------------------------------------------------- /app/Exceptions/AutoDeploymentException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions; 11 | 12 | use Exception; 13 | 14 | class AutoDeploymentException extends Exception 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /resources/scripts/api/server/schedules/deleteScheduleTask.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, scheduleId: number, taskId: number): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.delete(`/api/client/servers/${uuid}/schedules/${scheduleId}/tasks/${taskId}`) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /app/Exceptions/AccountNotFoundException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions; 11 | 12 | use Exception; 13 | 14 | class AccountNotFoundException extends Exception 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Events/Auth/ProvidedAuthenticationToken.php: -------------------------------------------------------------------------------- 1 | user = $user; 16 | $this->recovery = $recovery; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Extensions/Illuminate/Database/Eloquent/Builder.php: -------------------------------------------------------------------------------- 1 | ; 5 | 6 | export default ({ ns, children, ...props }: Props) => { 7 | const { t } = useTranslation(ns); 8 | 9 | return ( 10 | 11 | {children} 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /app/Exceptions/Service/HasActiveServersException.php: -------------------------------------------------------------------------------- 1 | => { 4 | return new Promise((resolve, reject) => { 5 | http.post('/auth/password', { email, 'g-recaptcha-response': recaptchaData }) 6 | .then((response) => resolve(response.data.status || '')) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/plugins/useDeepMemoize.ts: -------------------------------------------------------------------------------- 1 | import { DependencyList, MutableRefObject, useRef } from 'react'; 2 | import isEqual from 'react-fast-compare'; 3 | 4 | export const useDeepMemoize = (value: T): T => { 5 | const ref: MutableRefObject = useRef(); 6 | 7 | if (!isEqual(value, ref.current)) { 8 | ref.current = value; 9 | } 10 | 11 | return ref.current as T; 12 | }; 13 | -------------------------------------------------------------------------------- /app/Contracts/Repository/PermissionRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Contracts\Repository; 11 | 12 | interface PermissionRepositoryInterface extends RepositoryInterface 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /resources/scripts/api/server/network/createServerAllocation.ts: -------------------------------------------------------------------------------- 1 | import { Allocation } from '@/api/server/getServer'; 2 | import http from '@/api/http'; 3 | import { rawDataToServerAllocation } from '@/api/transformers'; 4 | 5 | export default async (uuid: string): Promise => { 6 | const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations`); 7 | 8 | return rawDataToServerAllocation(data); 9 | }; 10 | -------------------------------------------------------------------------------- /app/Contracts/Repository/ApiPermissionRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Contracts\Repository; 11 | 12 | interface ApiPermissionRepositoryInterface extends RepositoryInterface 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Database/TooManyDatabasesException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service\Helper; 11 | 12 | use Exception; 13 | 14 | class CdnVersionFetchingException extends Exception 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | => { 6 | const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}/primary`); 7 | 8 | return rawDataToServerAllocation(data); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/button/types.ts: -------------------------------------------------------------------------------- 1 | enum Shape { 2 | Default, 3 | IconSquare, 4 | } 5 | 6 | enum Size { 7 | Default, 8 | Small, 9 | Large, 10 | } 11 | 12 | enum Variant { 13 | Primary, 14 | Secondary, 15 | } 16 | 17 | export const Options = { Shape, Size, Variant }; 18 | 19 | export type ButtonProps = JSX.IntrinsicElements['button'] & { 20 | shape?: Shape; 21 | size?: Size; 22 | variant?: Variant; 23 | }; 24 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Egg/HasChildrenException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service\Egg; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class HasChildrenException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Traits/Controllers/PlainJavascriptInjection.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class InvalidFileUploadException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/UploadFileRequest.php: -------------------------------------------------------------------------------- 1 | app->make('view')->composer('*', AssetComposer::class); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Egg/InvalidCopyFromException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service\Egg; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class InvalidCopyFromException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Startup/GetStartupRequest.php: -------------------------------------------------------------------------------- 1 | => { 9 | return new Promise((resolve, reject) => { 10 | http.post(`/api/client/servers/${uuid}/files/chmod`, { root: directory, files }) 11 | .then(() => resolve()) 12 | .catch(reject); 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /resources/scripts/api/server/files/renameFiles.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | interface Data { 4 | to: string; 5 | from: string; 6 | } 7 | 8 | export default (uuid: string, directory: string, files: Data[]): Promise => { 9 | return new Promise((resolve, reject) => { 10 | http.put(`/api/client/servers/${uuid}/files/rename`, { root: directory, files }) 11 | .then(() => resolve()) 12 | .catch(reject); 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /app/Exceptions/Http/Server/FileTypeNotEditableException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Http\Server; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class FileTypeNotEditableException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Allocation/TooManyPortsInRangeException.php: -------------------------------------------------------------------------------- 1 | 4 |
5 |
6 | 您的面板当前配置为仅从环境中读取设置. 你需要将.env环境文件中的参数更改为 APP_ENVIRONMENT_ONLY=false 来保证程序动态加载设置. 7 |
8 |
9 | 10 | @endif 11 | @endsection 12 | -------------------------------------------------------------------------------- /app/Exceptions/Http/Base/InvalidPasswordProvidedException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Http\Base; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class InvalidPasswordProvidedException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Subuser/UserIsServerOwnerException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service\Subuser; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class UserIsServerOwnerException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /resources/scripts/api/server/network/setServerAllocationNotes.ts: -------------------------------------------------------------------------------- 1 | import { Allocation } from '@/api/server/getServer'; 2 | import http from '@/api/http'; 3 | import { rawDataToServerAllocation } from '@/api/transformers'; 4 | 5 | export default async (uuid: string, id: number, notes: string | null): Promise => { 6 | const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}`, { notes }); 7 | 8 | return rawDataToServerAllocation(data); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/activity/style.module.css: -------------------------------------------------------------------------------- 1 | .icons { 2 | @apply flex space-x-1 mx-2 transition-colors duration-100 text-gray-400; 3 | 4 | & > span { 5 | @apply px-1 py-px cursor-pointer hover:text-gray-50; 6 | } 7 | 8 | & svg { 9 | @apply w-4 h-4; 10 | } 11 | } 12 | 13 | .description { 14 | @apply mt-1 text-sm break-words line-clamp-2 pr-4; 15 | 16 | & strong { 17 | @apply text-gray-50 font-semibold; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Exceptions/Http/Server/FileSizeTooLargeException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service\Subuser; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class ServerSubuserExistsException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Egg/NoParentConfigurationFoundException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service\Egg; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class NoParentConfigurationFoundException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Settings/ReinstallServerRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|min:1', 18 | 'password' => 'required|string', 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Egg/Variable/ReservedVariableNameException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service\Egg\Variable; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class ReservedVariableNameException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Schedule/Task/TaskIntervalTooLongException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service\Schedule\Task; 11 | 12 | use Pterodactyl\Exceptions\DisplayException; 13 | 14 | class TaskIntervalTooLongException extends DisplayException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Server/RequiredVariableMissingException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Exceptions\Service\Server; 11 | 12 | use Pterodactyl\Exceptions\PterodactylException; 13 | 14 | class RequiredVariableMissingException extends PterodactylException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /app/Exceptions/Service/User/TwoFactorAuthenticationTokenInvalid.php: -------------------------------------------------------------------------------- 1 | => { 10 | return new Promise((resolve, reject) => { 11 | http.get('/api/client/account/two-factor') 12 | .then(({ data }) => resolve(data.data)) 13 | .catch(reject); 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /resources/scripts/easy-peasy.d.ts: -------------------------------------------------------------------------------- 1 | // noinspection ES6UnusedImports 2 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 3 | import EasyPeasy, { Actions, State } from 'easy-peasy'; 4 | import { ApplicationStore } from '@/state'; 5 | 6 | declare module 'easy-peasy' { 7 | export function useStoreState(mapState: (state: State) => Result): Result; 8 | 9 | export function useStoreActions(mapActions: (actions: Actions) => Result): Result; 10 | } 11 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Database/NoSuitableDatabaseHostException.php: -------------------------------------------------------------------------------- 1 | => { 4 | return new Promise((resolve, reject) => { 5 | http.get(`/api/client/servers/${server}/files/contents`, { 6 | params: { file }, 7 | transformResponse: (res) => res, 8 | responseType: 'text', 9 | }) 10 | .then(({ data }) => resolve(data)) 11 | .catch(reject); 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /resources/scripts/api/server/updateStartupVariable.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | import { ServerEggVariable } from '@/api/server/types'; 3 | import { rawDataToServerEggVariable } from '@/api/transformers'; 4 | 5 | export default async (uuid: string, key: string, value: string): Promise<[ServerEggVariable, string]> => { 6 | const { data } = await http.put(`/api/client/servers/${uuid}/startup/variable`, { key, value }); 7 | 8 | return [rawDataToServerEggVariable(data), data.meta.startup_command]; 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/dialog/context.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { DialogContextType, DialogWrapperContextType } from './types'; 3 | 4 | export const DialogContext = React.createContext({ 5 | setIcon: () => null, 6 | setFooter: () => null, 7 | setIconPosition: () => null, 8 | }); 9 | 10 | export const DialogWrapperContext = React.createContext({ 11 | props: {}, 12 | setProps: () => null, 13 | close: () => null, 14 | }); 15 | -------------------------------------------------------------------------------- /app/Listeners/Auth/TwoFactorListener.php: -------------------------------------------------------------------------------- 1 | recovery ? 'auth:recovery-token' : 'auth:token') 13 | ->withRequestMetadata() 14 | ->subject($event->user) 15 | ->log(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Models/Session.php: -------------------------------------------------------------------------------- 1 | 'string', 23 | 'user_id' => 'integer', 24 | ]; 25 | } 26 | -------------------------------------------------------------------------------- /resources/scripts/lib/strings.spec.ts: -------------------------------------------------------------------------------- 1 | import { capitalize } from '@/lib/strings'; 2 | 3 | describe('@/lib/strings.ts', function () { 4 | describe('capitalize()', function () { 5 | it('should capitalize a string', function () { 6 | expect(capitalize('foo bar')).toBe('Foo bar'); 7 | expect(capitalize('FOOBAR')).toBe('Foobar'); 8 | }); 9 | 10 | it('should handle empty strings', function () { 11 | expect(capitalize('')).toBe(''); 12 | }); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | . 5 | * Simplified Chinese Translation Copyright (c) 2021 - 2022 Ice Ling 6 | * 7 | * This software is licensed under the terms of the MIT license. 8 | * https://opensource.org/licenses/MIT 9 | */ 10 | return [ 11 | 'search' => '搜索服务器实例...', 12 | 'no_matches' => '未找到相关服务器.', 13 | 'cpu_title' => 'CPU', 14 | 'memory_title' => '运行内存', 15 | ]; 16 | -------------------------------------------------------------------------------- /app/Exceptions/Http/HttpForbiddenException.php: -------------------------------------------------------------------------------- 1 | env('APP_ACTIVITY_PRUNE_DAYS', 90), 6 | 7 | // If set to true activity log entries generated by an admin user that is not also 8 | // a part of the server in question will be hidden from the activity logs API response. 9 | // 10 | // Activity will still be properly tracked, just not displayed. 11 | 'hide_admin_activity' => env('APP_ACTIVITY_HIDE_ADMIN', false), 12 | ]; 13 | -------------------------------------------------------------------------------- /public/themes/pterodactyl/vendor/ace/mode-plain_text.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/plain_text",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/behaviour"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./text_highlight_rules").TextHighlightRules,o=e("./behaviour").Behaviour,u=function(){this.HighlightRules=s,this.$behaviour=new o};r.inherits(u,i),function(){this.type="text",this.getNextLineIndent=function(e,t,n){return""},this.$id="ace/mode/plain_text"}.call(u.prototype),t.Mode=u}) -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Nests/Eggs/GetEggRequest.php: -------------------------------------------------------------------------------- 1 | parameter('user', User::class)->id; 15 | 16 | return parent::rules(User::getRulesForUpdate($userId)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/inputs/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | import React, { forwardRef } from 'react'; 2 | import classNames from 'classnames'; 3 | import styles from './styles.module.css'; 4 | 5 | type Props = Omit, 'type'>; 6 | 7 | export default forwardRef(({ className, ...props }, ref) => ( 8 | 14 | )); 15 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Allocation/AutoAllocationNotEnabledException.php: -------------------------------------------------------------------------------- 1 | $port])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/BaseFormRequest.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Http\Requests\Admin; 11 | 12 | class BaseFormRequest extends AdminFormRequest 13 | { 14 | public function rules() 15 | { 16 | return [ 17 | 'company' => 'required|between:1,256', 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Users/GetExternalUserRequest.php: -------------------------------------------------------------------------------- 1 | field_type) { 12 | unset($variable->field_type); 13 | } 14 | } 15 | 16 | public function updating(EggVariable $variable): void 17 | { 18 | if ($variable->field_type) { 19 | unset($variable->field_type); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Locations/DeleteLocationRequest.php: -------------------------------------------------------------------------------- 1 | => { 4 | await http.post( 5 | `/api/client/servers/${uuid}/files/decompress`, 6 | { root: directory, file }, 7 | { 8 | timeout: 300000, 9 | timeoutErrorMessage: 10 | 'It looks like this archive is taking a long time to be unarchived. Once completed the unarchived files will appear.', 11 | } 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Backup/TooManyBackupsException.php: -------------------------------------------------------------------------------- 1 | => { 5 | return new Promise((resolve, reject) => { 6 | http.post(`/api/client/servers/${uuid}/databases/${database}/rotate-password`) 7 | .then((response) => resolve(rawDataToServerDatabase(response.data.attributes))) 8 | .catch(reject); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/GreyRowBox.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | import tw from 'twin.macro'; 3 | 4 | export default styled.div<{ $hoverable?: boolean }>` 5 | ${tw`flex rounded no-underline text-neutral-200 items-center bg-neutral-700 p-4 border border-transparent transition-colors duration-150 overflow-hidden`}; 6 | 7 | ${(props) => props.$hoverable !== false && tw`hover:border-neutral-500`}; 8 | 9 | & .icon { 10 | ${tw`rounded-full w-16 flex items-center justify-center bg-neutral-500 p-3`}; 11 | } 12 | `; 13 | -------------------------------------------------------------------------------- /resources/scripts/components/server/users/AddSubuserButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import EditSubuserModal from '@/components/server/users/EditSubuserModal'; 3 | import { Button } from '@/components/elements/button/index'; 4 | 5 | export default () => { 6 | const [visible, setVisible] = useState(false); 7 | 8 | return ( 9 | <> 10 | setVisible(false)} /> 11 | 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Allocation/NoAutoAllocationSpaceAvailableException.php: -------------------------------------------------------------------------------- 1 | 'present|boolean', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Requests/Auth/ResetPasswordRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string', 18 | 'email' => 'required|email', 19 | 'password' => 'required|string|confirmed|min:8', 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Repositories/Eloquent/ServerVariableRepository.php: -------------------------------------------------------------------------------- 1 | env('HASHIDS_SALT'), 13 | 'length' => env('HASHIDS_LENGTH', 8), 14 | 'alphabet' => env('HASHIDS_ALPHABET', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'), 15 | ]; 16 | -------------------------------------------------------------------------------- /app/Contracts/Repository/SessionRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | ' . PHP_EOL, $this->getUrl($path)); 10 | } 11 | 12 | public function css($path) 13 | { 14 | return sprintf('' . PHP_EOL, $this->getUrl($path)); 15 | } 16 | 17 | protected function getUrl($path) 18 | { 19 | return '/themes/pterodactyl/' . ltrim($path, '/'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/MountFormRequest.php: -------------------------------------------------------------------------------- 1 | method() === 'PATCH') { 17 | return Mount::getRulesForUpdate($this->route()->parameter('mount')->id); 18 | } 19 | 20 | return Mount::getRules(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Servers/Databases/GetServerDatabaseRequest.php: -------------------------------------------------------------------------------- 1 | toArray(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /config/egg_features/eula.php: -------------------------------------------------------------------------------- 1 | , document.getElementById('app')); 17 | -------------------------------------------------------------------------------- /resources/scripts/lib/helpers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Given a valid six character HEX color code, converts it into its associated 3 | * RGBA value with a user controllable alpha channel. 4 | */ 5 | function hexToRgba(hex: string, alpha = 1): string { 6 | // noinspection RegExpSimplifiable 7 | if (!/#?([a-fA-F0-9]{2}){3}/.test(hex)) { 8 | return hex; 9 | } 10 | 11 | // noinspection RegExpSimplifiable 12 | const [r, g, b] = hex.match(/[a-fA-F0-9]{2}/g)!.map((v) => parseInt(v, 16)); 13 | 14 | return `rgba(${r}, ${g}, ${b}, ${alpha})`; 15 | } 16 | 17 | export { hexToRgba }; 18 | -------------------------------------------------------------------------------- /app/Exceptions/Service/ServiceLimitExceededException.php: -------------------------------------------------------------------------------- 1 | 'required|string', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /database/Factories/TaskFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->numberBetween(1, 10), 16 | 'action' => 'command', 17 | 'payload' => 'test command', 18 | 'time_offset' => 120, 19 | 'is_queued' => false, 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /database/migrations/2016_10_23_181719_update_misnamed_bungee.php: -------------------------------------------------------------------------------- 1 | select('env_variable')->where('env_variable', 'BUNGE_VERSION')->update([ 13 | 'env_variable' => 'BUNGEE_VERSION', 14 | ]); 15 | } 16 | 17 | /** 18 | * Reverse the migrations. 19 | */ 20 | public function down() 21 | { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /resources/scripts/api/server/getWebsocketToken.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | interface Response { 4 | token: string; 5 | socket: string; 6 | } 7 | 8 | export default (server: string): Promise => { 9 | return new Promise((resolve, reject) => { 10 | http.get(`/api/client/servers/${server}/websocket`) 11 | .then(({ data }) => 12 | resolve({ 13 | token: data.data.token, 14 | socket: data.data.socket, 15 | }) 16 | ) 17 | .catch(reject); 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Nodes/GetDeployableNodesRequest.php: -------------------------------------------------------------------------------- 1 | 'integer', 14 | 'memory' => 'required|integer|min:0', 15 | 'disk' => 'required|integer|min:0', 16 | 'location_ids' => 'array', 17 | 'location_ids.*' => 'integer', 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Repositories/Eloquent/PermissionRepository.php: -------------------------------------------------------------------------------- 1 | { 6 | const { setFooter } = useContext(DialogContext); 7 | 8 | useDeepCompareEffect(() => { 9 | setFooter( 10 |
{children}
11 | ); 12 | }, [children]); 13 | 14 | return null; 15 | }; 16 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/DownloadFileRequest.php: -------------------------------------------------------------------------------- 1 | user()->can('file.read', $this->parameter('server', Server::class)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Events/Server/Installed.php: -------------------------------------------------------------------------------- 1 | server = $server; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /resources/scripts/state/settings.ts: -------------------------------------------------------------------------------- 1 | import { action, Action } from 'easy-peasy'; 2 | 3 | export interface SiteSettings { 4 | name: string; 5 | locale: string; 6 | recaptcha: { 7 | enabled: boolean; 8 | siteKey: string; 9 | }; 10 | } 11 | 12 | export interface SettingsStore { 13 | data?: SiteSettings; 14 | setSettings: Action; 15 | } 16 | 17 | const settings: SettingsStore = { 18 | data: undefined, 19 | 20 | setSettings: action((state, payload) => { 21 | state.data = payload; 22 | }), 23 | }; 24 | 25 | export default settings; 26 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Subusers/UpdateSubuserRequest.php: -------------------------------------------------------------------------------- 1 | 'required|array', 21 | 'permissions.*' => 'string', 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /resources/lang/en/admin/user.php: -------------------------------------------------------------------------------- 1 | . 5 | * Simplified Chinese Translation Copyright (c) 2021 - 2022 Ice Ling 6 | * 7 | * This software is licensed under the terms of the MIT license. 8 | * https://opensource.org/licenses/MIT 9 | */ 10 | 11 | return [ 12 | 'exceptions' => [ 13 | 'user_has_servers' => '此账户名下有服务器实例,请将其全部删除再进行账户删除操作.', 14 | ], 15 | 'notices' => [ 16 | 'account_created' => '账户已成功创建.', 17 | 'account_updated' => '账户信息已成功更新.', 18 | ], 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/scripts/api/server/schedules/getServerSchedule.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | import { rawDataToServerSchedule, Schedule } from '@/api/server/schedules/getServerSchedules'; 3 | 4 | export default (uuid: string, schedule: number): Promise => { 5 | return new Promise((resolve, reject) => { 6 | http.get(`/api/client/servers/${uuid}/schedules/${schedule}`, { 7 | params: { 8 | include: ['tasks'], 9 | }, 10 | }) 11 | .then(({ data }) => resolve(rawDataToServerSchedule(data.attributes))) 12 | .catch(reject); 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Locations/UpdateLocationRequest.php: -------------------------------------------------------------------------------- 1 | route()->parameter('location')->id; 15 | 16 | return collect(Location::getRulesForUpdate($locationId))->only([ 17 | 'short', 18 | 'long', 19 | ])->toArray(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/Factories/ScheduleFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->firstName(), 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | $uri = urldecode( 9 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 10 | ); 11 | 12 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 13 | // built-in PHP web server. This provides a convenient way to test a Laravel 14 | // application without having installed a "real" web server software here. 15 | if ($uri !== '/' && file_exists(__DIR__ . '/public' . $uri)) { 16 | return false; 17 | } 18 | 19 | require_once __DIR__ . '/public/index.php'; 20 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Nodes/UpdateNodeRequest.php: -------------------------------------------------------------------------------- 1 | route()->parameter('node')->id; 16 | 17 | return parent::rules(Node::getRulesForUpdate($node)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /resources/scripts/api/account/updateAccountPassword.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | interface Data { 4 | current: string; 5 | password: string; 6 | confirmPassword: string; 7 | } 8 | 9 | export default ({ current, password, confirmPassword }: Data): Promise => { 10 | return new Promise((resolve, reject) => { 11 | http.put('/api/client/account/password', { 12 | current_password: current, 13 | password: password, 14 | password_confirmation: confirmPassword, 15 | }) 16 | .then(() => resolve()) 17 | .catch(reject); 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /app/Http/Middleware/Activity/AccountSubject.php: -------------------------------------------------------------------------------- 1 | user()); 18 | LogTarget::setSubject($request->user()); 19 | 20 | return $next($request); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Jobs/Job.php: -------------------------------------------------------------------------------- 1 | $egg->uuid, 24 | 'name' => $egg->name, 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/AuthenticatedRoute.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Redirect, Route, RouteProps } from 'react-router'; 3 | import { useStoreState } from '@/state/hooks'; 4 | 5 | export default ({ children, ...props }: Omit) => { 6 | const isAuthenticated = useStoreState((state) => !!state.user.data?.uuid); 7 | 8 | return ( 9 | 12 | isAuthenticated ? children : 13 | } 14 | /> 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/Code.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classNames from 'classnames'; 3 | 4 | interface CodeProps { 5 | dark?: boolean | undefined; 6 | className?: string; 7 | children: React.ReactChild | React.ReactFragment | React.ReactPortal; 8 | } 9 | 10 | export default ({ dark, className, children }: CodeProps) => ( 11 | 17 | {children} 18 | 19 | ); 20 | -------------------------------------------------------------------------------- /app/Models/Setting.php: -------------------------------------------------------------------------------- 1 | 'required|string|between:1,191', 29 | 'value' => 'string', 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /app/Listeners/Auth/PasswordResetListener.php: -------------------------------------------------------------------------------- 1 | request = $request; 16 | } 17 | 18 | public function handle(PasswordReset $event) 19 | { 20 | Activity::event('event:password-reset') 21 | ->withRequestMetadata() 22 | ->subject($event->user) 23 | ->log(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | id === (int) $userId; 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Contracts/Repository/AllocationRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | 'required|string', 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Remote/ReportBackupCompleteRequest.php: -------------------------------------------------------------------------------- 1 | 'required|boolean', 16 | 'checksum' => 'nullable|string|required_if:successful,true', 17 | 'checksum_type' => 'nullable|string|required_if:successful,true', 18 | 'size' => 'nullable|numeric|required_if:successful,true', 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/scripts/api/server/types.d.ts: -------------------------------------------------------------------------------- 1 | export type ServerStatus = 'installing' | 'install_failed' | 'suspended' | 'restoring_backup' | null; 2 | 3 | export interface ServerBackup { 4 | uuid: string; 5 | isSuccessful: boolean; 6 | isLocked: boolean; 7 | name: string; 8 | ignoredFiles: string; 9 | checksum: string; 10 | bytes: number; 11 | createdAt: Date; 12 | completedAt: Date | null; 13 | } 14 | 15 | export interface ServerEggVariable { 16 | name: string; 17 | description: string; 18 | envVariable: string; 19 | defaultValue: string; 20 | serverValue: string; 21 | isEditable: boolean; 22 | rules: string[]; 23 | } 24 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Subusers/StoreSubuserRequest.php: -------------------------------------------------------------------------------- 1 | 'required|email|between:1,191', 21 | 'permissions' => 'required|array', 22 | 'permissions.*' => 'string', 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Providers/ActivityLogServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->scoped(AcitvityLogBatchService::class); 18 | $this->app->scoped(ActivityLogTargetableService::class); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /database/migrations/2016_01_23_203119_create_settings_table.php: -------------------------------------------------------------------------------- 1 | string('key')->unique(); 15 | $table->text('value'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::dropIfExists('settings'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /resources/scripts/context/ModalContext.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { SettableModalProps } from '@/hoc/asModal'; 3 | 4 | export interface ModalContextValues { 5 | dismiss: () => void; 6 | setPropOverrides: ( 7 | value: 8 | | ((current: Readonly>) => Partial) 9 | | Partial 10 | | null 11 | ) => void; 12 | } 13 | 14 | const ModalContext = React.createContext({ 15 | dismiss: () => null, 16 | setPropOverrides: () => null, 17 | }); 18 | 19 | ModalContext.displayName = 'ModalContext'; 20 | 21 | export default ModalContext; 22 | -------------------------------------------------------------------------------- /app/Contracts/Criteria/CriteriaInterface.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Contracts\Criteria; 11 | 12 | use Pterodactyl\Repositories\Repository; 13 | 14 | interface CriteriaInterface 15 | { 16 | /** 17 | * Apply selected criteria to a repository call. 18 | * 19 | * @param \Illuminate\Database\Eloquent\Model $model 20 | * 21 | * @return mixed 22 | */ 23 | public function apply($model, Repository $repository); 24 | } 25 | -------------------------------------------------------------------------------- /app/Providers/BladeServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->make('blade.compiler') 15 | ->directive('datetimeHuman', function ($expression) { 16 | return "setTimezone(config('app.timezone'))->toDateTimeString(); ?>"; 17 | }); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /resources/scripts/api/server/backups/createServerBackup.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | import { ServerBackup } from '@/api/server/types'; 3 | import { rawDataToServerBackup } from '@/api/transformers'; 4 | 5 | interface RequestParameters { 6 | name?: string; 7 | ignored?: string; 8 | isLocked: boolean; 9 | } 10 | 11 | export default async (uuid: string, params: RequestParameters): Promise => { 12 | const { data } = await http.post(`/api/client/servers/${uuid}/backups`, { 13 | name: params.name, 14 | ignored: params.ignored, 15 | is_locked: params.isLocked, 16 | }); 17 | 18 | return rawDataToServerBackup(data); 19 | }; 20 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /app/Extensions/Laravel/Sanctum/NewAccessToken.php: -------------------------------------------------------------------------------- 1 | accessToken = $accessToken; 21 | $this->plainTextToken = $plainTextToken; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /database/Factories/LocationFactory.php: -------------------------------------------------------------------------------- 1 | Str::random(8), 25 | 'long' => Str::random(32), 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /resources/scripts/state/server/socket.ts: -------------------------------------------------------------------------------- 1 | import { Action, action } from 'easy-peasy'; 2 | import { Websocket } from '@/plugins/Websocket'; 3 | 4 | export interface SocketStore { 5 | instance: Websocket | null; 6 | connected: boolean; 7 | setInstance: Action; 8 | setConnectionState: Action; 9 | } 10 | 11 | const socket: SocketStore = { 12 | instance: null, 13 | connected: false, 14 | setInstance: action((state, payload) => { 15 | state.instance = payload; 16 | }), 17 | setConnectionState: action((state, payload) => { 18 | state.connected = payload; 19 | }), 20 | }; 21 | 22 | export default socket; 23 | -------------------------------------------------------------------------------- /app/Contracts/Repository/ScheduleRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | renameColumn('permissions', 'permission'); 15 | }); 16 | } 17 | 18 | /** 19 | * Reverse the migrations. 20 | */ 21 | public function down() 22 | { 23 | Schema::table('permissions', function (Blueprint $table) { 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /routes/base.php: -------------------------------------------------------------------------------- 1 | name('index')->fallback(); 7 | Route::get('/account', [Base\IndexController::class, 'index']) 8 | ->withoutMiddleware(RequireTwoFactorAuthentication::class) 9 | ->name('account'); 10 | 11 | Route::get('/locales/locale.json', Base\LocaleController::class) 12 | ->withoutMiddleware(['auth', RequireTwoFactorAuthentication::class]) 13 | ->where('namespace', '.*'); 14 | 15 | Route::get('/{react}', [Base\IndexController::class, 'index']) 16 | ->where('react', '^(?!(\/)?(api|auth|admin|daemon)).+'); 17 | -------------------------------------------------------------------------------- /app/Console/Commands/Overrides/UpCommand.php: -------------------------------------------------------------------------------- 1 | hasCompletedMigrations()) { 19 | $this->showMigrationWarning(); 20 | 21 | return; 22 | } 23 | 24 | parent::handle(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/ServerContentBlock.tsx: -------------------------------------------------------------------------------- 1 | import PageContentBlock, { PageContentBlockProps } from '@/components/elements/PageContentBlock'; 2 | import React from 'react'; 3 | import { ServerContext } from '@/state/server'; 4 | 5 | interface Props extends PageContentBlockProps { 6 | title: string; 7 | } 8 | 9 | const ServerContentBlock: React.FC = ({ title, children, ...props }) => { 10 | const name = ServerContext.useStoreState((state) => state.server.data!.name); 11 | 12 | return ( 13 | 14 | {children} 15 | 16 | ); 17 | }; 18 | 19 | export default ServerContentBlock; 20 | -------------------------------------------------------------------------------- /resources/scripts/components/server/UptimeDuration.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default ({ uptime }: { uptime: number }) => { 4 | const days = Math.floor(uptime / (24 * 60 * 60)); 5 | const hours = Math.floor((Math.floor(uptime) / 60 / 60) % 24); 6 | const remainder = Math.floor(uptime - hours * 60 * 60); 7 | const minutes = Math.floor((remainder / 60) % 60); 8 | const seconds = remainder % 60; 9 | 10 | if (days > 0) { 11 | return ( 12 | <> 13 | {days}d {hours}h {minutes}m 14 | 15 | ); 16 | } 17 | 18 | return ( 19 | <> 20 | {hours}h {minutes}m {seconds}s 21 | 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Network/UpdateAllocationRequest.php: -------------------------------------------------------------------------------- 1 | array_merge($rules['notes'], ['present']), 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Exceptions/Repository/RecordNotFoundException.php: -------------------------------------------------------------------------------- 1 | => { 11 | return new Promise((resolve, reject) => { 12 | http.post(`/api/client/servers/${uuid}/users${subuser ? `/${subuser.uuid}` : ''}`, { 13 | ...params, 14 | }) 15 | .then((data) => resolve(rawDataToServerSubuser(data.data))) 16 | .catch(reject); 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /app/Console/Commands/Overrides/SeedCommand.php: -------------------------------------------------------------------------------- 1 | hasCompletedMigrations()) { 19 | $this->showMigrationWarning(); 20 | 21 | return; 22 | } 23 | 24 | parent::handle(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Contracts/Repository/EggVariableRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Contracts\Repository; 11 | 12 | use Illuminate\Support\Collection; 13 | 14 | interface EggVariableRepositoryInterface extends RepositoryInterface 15 | { 16 | /** 17 | * Return editable variables for a given egg. Editable variables must be set to 18 | * user viewable in order to be picked up by this function. 19 | */ 20 | public function getEditableVariables(int $egg): Collection; 21 | } 22 | -------------------------------------------------------------------------------- /database/Factories/SubuserFactory.php: -------------------------------------------------------------------------------- 1 | [ 25 | Permission::ACTION_WEBSOCKET_CONNECT, 26 | ], 27 | ]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /resources/scripts/api/server/files/compressFiles.ts: -------------------------------------------------------------------------------- 1 | import { FileObject } from '@/api/server/files/loadDirectory'; 2 | import http from '@/api/http'; 3 | import { rawDataToFileObject } from '@/api/transformers'; 4 | 5 | export default async (uuid: string, directory: string, files: string[]): Promise => { 6 | const { data } = await http.post( 7 | `/api/client/servers/${uuid}/files/compress`, 8 | { root: directory, files }, 9 | { 10 | timeout: 60000, 11 | timeoutErrorMessage: 12 | 'It looks like this archive is taking a long time to generate. It will appear once completed.', 13 | } 14 | ); 15 | 16 | return rawDataToFileObject(data); 17 | }; 18 | -------------------------------------------------------------------------------- /resources/scripts/components/server/events.ts: -------------------------------------------------------------------------------- 1 | export enum SocketEvent { 2 | DAEMON_MESSAGE = 'daemon message', 3 | DAEMON_ERROR = 'daemon error', 4 | INSTALL_OUTPUT = 'install output', 5 | INSTALL_STARTED = 'install started', 6 | INSTALL_COMPLETED = 'install completed', 7 | CONSOLE_OUTPUT = 'console output', 8 | STATUS = 'status', 9 | STATS = 'stats', 10 | TRANSFER_LOGS = 'transfer logs', 11 | TRANSFER_STATUS = 'transfer status', 12 | BACKUP_COMPLETED = 'backup completed', 13 | BACKUP_RESTORE_COMPLETED = 'backup restore completed', 14 | } 15 | 16 | export enum SocketRequest { 17 | SEND_LOGS = 'send logs', 18 | SEND_STATS = 'send stats', 19 | SET_STATE = 'set state', 20 | } 21 | -------------------------------------------------------------------------------- /.github/workflows/buildtest.yml: -------------------------------------------------------------------------------- 1 | name: Main Branch Assests Build Test 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | pull_request: 7 | jobs: 8 | build: 9 | runs-on: ubuntu-20.04 10 | if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, 'ci skip')" 11 | strategy: 12 | matrix: 13 | node-version: [16.x] 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v2 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | cache: 'npm' 21 | - run: npm install -g yarn 22 | - run: yarn install 23 | - run: yarn build:production 24 | -------------------------------------------------------------------------------- /app/Exceptions/Http/TwoFactorAuthRequiredException.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Http\Requests\Admin\Nest; 11 | 12 | use Pterodactyl\Http\Requests\Admin\AdminFormRequest; 13 | 14 | class StoreNestFormRequest extends AdminFormRequest 15 | { 16 | /** 17 | * @return array 18 | */ 19 | public function rules() 20 | { 21 | return [ 22 | 'name' => 'required|string|min:1|max:191', 23 | 'description' => 'string|nullable', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Backups/StoreBackupRequest.php: -------------------------------------------------------------------------------- 1 | 'nullable|string|max:191', 22 | 'is_locked' => 'nullable|boolean', 23 | 'ignored' => 'nullable|string', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /config/http.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'client_period' => 1, 16 | 'client' => env('APP_API_CLIENT_RATELIMIT', 720), 17 | 18 | 'application_period' => 1, 19 | 'application' => env('APP_API_APPLICATION_RATELIMIT', 240), 20 | ], 21 | ]; 22 | -------------------------------------------------------------------------------- /database/migrations/2016_03_18_155649_add_nullable_field_lastrun.php: -------------------------------------------------------------------------------- 1 | wrapTable('tasks'); 13 | DB::statement('ALTER TABLE ' . $table . ' CHANGE `last_run` `last_run` TIMESTAMP NULL;'); 14 | } 15 | 16 | /** 17 | * Reverse the migrations. 18 | */ 19 | public function down() 20 | { 21 | $table = DB::getQueryGrammar()->wrapTable('tasks'); 22 | DB::statement('ALTER TABLE ' . $table . ' CHANGE `last_run` `last_run` TIMESTAMP;'); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /database/migrations/2016_01_23_200044_add_api_permissions.php: -------------------------------------------------------------------------------- 1 | increments('id'); 15 | $table->mediumInteger('key_id')->unsigned(); 16 | $table->string('permission'); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down() 24 | { 25 | Schema::dropIfExists('api_permissions'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/migrations/2016_01_23_200528_add_locations.php: -------------------------------------------------------------------------------- 1 | increments('id'); 15 | $table->string('short')->unique(); 16 | $table->string('long'); 17 | $table->timestamps(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | */ 24 | public function down() 25 | { 26 | Schema::dropIfExists('locations'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/migrations/2016_01_23_201433_add_password_resets.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 15 | $table->string('token')->index(); 16 | $table->timestamp('created_at'); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down() 24 | { 25 | Schema::dropIfExists('password_resets'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/CreateFolderRequest.php: -------------------------------------------------------------------------------- 1 | 'sometimes|nullable|string', 22 | 'name' => 'required|string', 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /database/migrations/2016_02_20_155318_add_unique_service_field.php: -------------------------------------------------------------------------------- 1 | string('file')->unique()->change(); 15 | }); 16 | } 17 | 18 | /** 19 | * Reverse the migrations. 20 | */ 21 | public function down() 22 | { 23 | Schema::table('services', function (Blueprint $table) { 24 | $table->dropUnique('services_file_unique'); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/migrations/2016_09_01_211924_remove_active_column.php: -------------------------------------------------------------------------------- 1 | dropColumn('active'); 15 | }); 16 | } 17 | 18 | /** 19 | * Reverse the migrations. 20 | */ 21 | public function down() 22 | { 23 | Schema::table('servers', function (Blueprint $table) { 24 | $table->tinyInteger('active')->after('name')->unsigned()->default(0); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/migrations/2016_09_29_213518_rename_double_insurgency.php: -------------------------------------------------------------------------------- 1 | where('parent_service', 2)->where('id', 3)->where('name', 'Insurgency')->first(); 14 | if ($model) { 15 | $model->name = 'Team Fortress 2'; 16 | $model->save(); 17 | } 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | */ 24 | public function down() 25 | { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/ListFilesRequest.php: -------------------------------------------------------------------------------- 1 | 'sometimes|nullable|string', 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /database/migrations/2022_01_25_030847_drop_google_analytics.php: -------------------------------------------------------------------------------- 1 | where('key', 'settings::app:analytics')->delete(); 16 | } 17 | 18 | /** 19 | * Reverse the migrations. 20 | * 21 | * @return void 22 | */ 23 | public function down() 24 | { 25 | DB::table('settings')->insert( 26 | [ 27 | 'key' => 'settings::app:analytics', 28 | ] 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/SendCommandRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|min:1', 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/migrations/2016_09_02_190647_add_sftp_password_storage.php: -------------------------------------------------------------------------------- 1 | text('sftp_password')->after('username')->nullable(); 15 | }); 16 | } 17 | 18 | /** 19 | * Reverse the migrations. 20 | */ 21 | public function down() 22 | { 23 | Schema::table('servers', function (Blueprint $table) { 24 | $table->dropColumn('sftp_password'); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/Node/AllocationAliasFormRequest.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Http\Requests\Admin\Node; 11 | 12 | use Pterodactyl\Http\Requests\Admin\AdminFormRequest; 13 | 14 | class AllocationAliasFormRequest extends AdminFormRequest 15 | { 16 | /** 17 | * @return array 18 | */ 19 | public function rules() 20 | { 21 | return [ 22 | 'alias' => 'present|nullable|string', 23 | 'allocation_id' => 'required|numeric|exists:allocations,id', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/DeleteFileRequest.php: -------------------------------------------------------------------------------- 1 | 'required|nullable|string', 20 | 'files' => 'required|array', 21 | 'files.*' => 'string', 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Providers/BackupsServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->singleton(BackupManager::class, function ($app) { 17 | return new BackupManager($app); 18 | }); 19 | } 20 | 21 | /** 22 | * @return string[] 23 | */ 24 | public function provides() 25 | { 26 | return [BackupManager::class]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/migrations/2017_07_24_194433_DeleteTaskWhenParentServerIsDeleted.php: -------------------------------------------------------------------------------- 1 | dropForeign(['server_id']); 16 | 17 | $table->foreign('server_id')->references('id')->on('servers')->onDelete('cascade'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | */ 24 | public function down() 25 | { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/migrations/2016_09_01_193520_add_suspension_for_servers.php: -------------------------------------------------------------------------------- 1 | tinyInteger('suspended')->unsigned()->default(0)->after('active'); 15 | }); 16 | } 17 | 18 | /** 19 | * Reverse the migrations. 20 | */ 21 | public function down() 22 | { 23 | Schema::table('servers', function (Blueprint $table) { 24 | $table->dropColumn('suspended'); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/migrations/2016_09_04_172028_update_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | text('exception'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('failed_jobs', function (Blueprint $table) { 25 | $table->dropColumn('exception'); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/migrations/2016_09_07_163017_add_unique_identifier.php: -------------------------------------------------------------------------------- 1 | char('author', 36)->after('id'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('services', function (Blueprint $table) { 25 | $table->dropColumn('author'); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/migrations/2016_11_11_231731_set_service_name_unique.php: -------------------------------------------------------------------------------- 1 | unique('name'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('services', function (Blueprint $table) { 25 | $table->dropUnique('services_name_unique'); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/Unit/Http/Middleware/MiddlewareTestCase.php: -------------------------------------------------------------------------------- 1 | buildRequestMock(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /resources/scripts/hoc/RequireServerPermission.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Can from '@/components/elements/Can'; 3 | import { ServerError } from '@/components/elements/ScreenBlock'; 4 | 5 | export interface RequireServerPermissionProps { 6 | permissions: string | string[]; 7 | } 8 | 9 | const RequireServerPermission: React.FC = ({ children, permissions }) => { 10 | return ( 11 | 15 | } 16 | > 17 | {children} 18 | 19 | ); 20 | }; 21 | 22 | export default RequireServerPermission; 23 | -------------------------------------------------------------------------------- /app/Events/User/Created.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\User; 11 | 12 | use Pterodactyl\Models\User; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Created 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\User 23 | */ 24 | public $user; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(User $user) 30 | { 31 | $this->user = $user; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/User/Creating.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\User; 11 | 12 | use Pterodactyl\Models\User; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Creating 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\User 23 | */ 24 | public $user; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(User $user) 30 | { 31 | $this->user = $user; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/User/Deleted.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\User; 11 | 12 | use Pterodactyl\Models\User; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Deleted 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\User 23 | */ 24 | public $user; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(User $user) 30 | { 31 | $this->user = $user; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/User/Deleting.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\User; 11 | 12 | use Pterodactyl\Models\User; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Deleting 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\User 23 | */ 24 | public $user; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(User $user) 30 | { 31 | $this->user = $user; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/UserFormRequest.php: -------------------------------------------------------------------------------- 1 | route()->parameter('user')) 18 | )->only([ 19 | 'email', 20 | 'username', 21 | 'name_first', 22 | 'name_last', 23 | 'password', 24 | 'language', 25 | 'root_admin', 26 | ])->toArray(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Transformers/Api/Client/UserSSHKeyTransformer.php: -------------------------------------------------------------------------------- 1 | $model->name, 21 | 'fingerprint' => $model->fingerprint, 22 | 'public_key' => $model->public_key, 23 | 'created_at' => $model->created_at->toIso8601String(), 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /database/Factories/NestFactory.php: -------------------------------------------------------------------------------- 1 | Uuid::uuid4()->toString(), 25 | 'author' => 'testauthor@example.com', 26 | 'name' => $this->faker->word, 27 | 'description' => null, 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /database/migrations/2016_10_23_204610_add_foreign_tasks.php: -------------------------------------------------------------------------------- 1 | foreign('server')->references('id')->on('servers'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('tasks', function (Blueprint $table) { 25 | $table->dropForeign(['server']); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /resources/scripts/api/swr/getServerAllocations.ts: -------------------------------------------------------------------------------- 1 | import { ServerContext } from '@/state/server'; 2 | import useSWR from 'swr'; 3 | import http from '@/api/http'; 4 | import { rawDataToServerAllocation } from '@/api/transformers'; 5 | import { Allocation } from '@/api/server/getServer'; 6 | 7 | export default () => { 8 | const uuid = ServerContext.useStoreState((state) => state.server.data!.uuid); 9 | 10 | return useSWR( 11 | ['server:allocations', uuid], 12 | async () => { 13 | const { data } = await http.get(`/api/client/servers/${uuid}/network/allocations`); 14 | 15 | return (data.data || []).map(rawDataToServerAllocation); 16 | }, 17 | { revalidateOnFocus: false, revalidateOnMount: false } 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/Can.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from 'react'; 2 | import { usePermissions } from '@/plugins/usePermissions'; 3 | import isEqual from 'react-fast-compare'; 4 | 5 | interface Props { 6 | action: string | string[]; 7 | matchAny?: boolean; 8 | renderOnError?: React.ReactNode | null; 9 | children: React.ReactNode; 10 | } 11 | 12 | const Can = ({ action, matchAny = false, renderOnError, children }: Props) => { 13 | const can = usePermissions(action); 14 | 15 | return ( 16 | <> 17 | {(matchAny && can.filter((p) => p).length > 0) || (!matchAny && can.every((p) => p)) 18 | ? children 19 | : renderOnError} 20 | 21 | ); 22 | }; 23 | 24 | export default memo(Can, isEqual); 25 | -------------------------------------------------------------------------------- /resources/scripts/plugins/useUserSWRContentKey.ts: -------------------------------------------------------------------------------- 1 | import { useStoreState } from '@/state/hooks'; 2 | import { useDeepCompareMemo } from '@/plugins/useDeepCompareMemo'; 3 | 4 | // eslint-disable-next-line @typescript-eslint/ban-types 5 | export default (context: string | string[] | (string | number | null | {})[]) => { 6 | const uuid = useStoreState((state) => state.user.data?.uuid); 7 | const key = useDeepCompareMemo((): string => { 8 | return (Array.isArray(context) ? context : [context]).map((value) => JSON.stringify(value)).join(':'); 9 | }, [context]); 10 | 11 | if (!key.trim().length) { 12 | throw new Error('Must provide a valid context key to "useUserSWRContextKey".'); 13 | } 14 | 15 | return `swr::${uuid || 'unknown'}:${key.trim()}`; 16 | }; 17 | -------------------------------------------------------------------------------- /database/migrations/2016_01_23_195851_add_api_keys.php: -------------------------------------------------------------------------------- 1 | increments('id'); 15 | $table->char('public', 16); 16 | $table->text('secret'); 17 | $table->text('allowed_ips')->nullable(); 18 | $table->timestamps(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | */ 25 | public function down() 26 | { 27 | Schema::dropIfExists('api_keys'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /database/migrations/2016_01_23_200159_add_downloads.php: -------------------------------------------------------------------------------- 1 | increments('id'); 15 | $table->char('token', 36)->unique(); 16 | $table->char('server', 36); 17 | $table->text('path'); 18 | $table->timestamps(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | */ 25 | public function down() 26 | { 27 | Schema::dropIfExists('downloads'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /database/migrations/2016_09_14_145945_allow_longer_regex_field.php: -------------------------------------------------------------------------------- 1 | text('regex')->change(); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('service_variables', function (Blueprint $table) { 25 | $table->string('regex')->change(); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/migrations/2017_03_14_200326_AddLockedStatusToTable.php: -------------------------------------------------------------------------------- 1 | boolean('locked')->default(false)->after('visible'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('packs', function (Blueprint $table) { 25 | $table->dropColumn('locked'); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/migrations/2017_03_18_204953_AddForeignKeyToPacks.php: -------------------------------------------------------------------------------- 1 | foreign('pack_id')->references('id')->on('packs'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('servers', function (Blueprint $table) { 25 | $table->dropForeign(['pack_id']); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/migrations/2017_03_31_221948_AddServerDescriptionColumn.php: -------------------------------------------------------------------------------- 1 | text('description')->after('name'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('servers', function (Blueprint $table) { 25 | $table->dropColumn('description'); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Events/Server/Saved.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Server; 11 | 12 | use Pterodactyl\Models\Server; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Saved 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Server 23 | */ 24 | public $server; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Server $server) 30 | { 31 | $this->server = $server; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/Server/Saving.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Server; 11 | 12 | use Pterodactyl\Models\Server; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Saving 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Server 23 | */ 24 | public $server; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Server $server) 30 | { 31 | $this->server = $server; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/CompressFilesRequest.php: -------------------------------------------------------------------------------- 1 | 'sometimes|nullable|string', 22 | 'files' => 'required|array', 23 | 'files.*' => 'string', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /database/migrations/2017_04_02_163232_DropDeletedAtColumnFromServers.php: -------------------------------------------------------------------------------- 1 | dropColumn('deleted_at'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('servers', function (Blueprint $table) { 25 | $table->timestamp('deleted_at')->nullable(); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /resources/scripts/state/index.ts: -------------------------------------------------------------------------------- 1 | import { createStore } from 'easy-peasy'; 2 | import flashes, { FlashStore } from '@/state/flashes'; 3 | import user, { UserStore } from '@/state/user'; 4 | import permissions, { GloablPermissionsStore } from '@/state/permissions'; 5 | import settings, { SettingsStore } from '@/state/settings'; 6 | import progress, { ProgressStore } from '@/state/progress'; 7 | 8 | export interface ApplicationStore { 9 | permissions: GloablPermissionsStore; 10 | flashes: FlashStore; 11 | user: UserStore; 12 | settings: SettingsStore; 13 | progress: ProgressStore; 14 | } 15 | 16 | const state: ApplicationStore = { 17 | permissions, 18 | flashes, 19 | user, 20 | settings, 21 | progress, 22 | }; 23 | 24 | export const store = createStore(state); 25 | -------------------------------------------------------------------------------- /app/Events/Server/Created.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Server; 11 | 12 | use Pterodactyl\Models\Server; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Created 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Server 23 | */ 24 | public $server; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Server $server) 30 | { 31 | $this->server = $server; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/Server/Creating.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Server; 11 | 12 | use Pterodactyl\Models\Server; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Creating 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Server 23 | */ 24 | public $server; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Server $server) 30 | { 31 | $this->server = $server; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/Server/Deleted.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Server; 11 | 12 | use Pterodactyl\Models\Server; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Deleted 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Server 23 | */ 24 | public $server; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Server $server) 30 | { 31 | $this->server = $server; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/Server/Deleting.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Server; 11 | 12 | use Pterodactyl\Models\Server; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Deleting 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Server 23 | */ 24 | public $server; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Server $server) 30 | { 31 | $this->server = $server; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/Server/Updated.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Server; 11 | 12 | use Pterodactyl\Models\Server; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Updated 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Server 23 | */ 24 | public $server; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Server $server) 30 | { 31 | $this->server = $server; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/Server/Updating.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Server; 11 | 12 | use Pterodactyl\Models\Server; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Updating 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Server 23 | */ 24 | public $server; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Server $server) 30 | { 31 | $this->server = $server; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2016_09_21_165554_update_servers_column_name.php: -------------------------------------------------------------------------------- 1 | renameColumn('server', 'server_id'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('databases', function (Blueprint $table) { 25 | $table->renameColumn('server_id', 'server'); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Contracts/Extensions/HashidsInterface.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Contracts\Extensions; 11 | 12 | use Hashids\HashidsInterface as VendorHashidsInterface; 13 | 14 | interface HashidsInterface extends VendorHashidsInterface 15 | { 16 | /** 17 | * Decode an encoded hashid and return the first result. 18 | * 19 | * @param string $encoded 20 | * @param null $default 21 | * 22 | * @return mixed 23 | * 24 | * @throws \InvalidArgumentException 25 | */ 26 | public function decodeFirst($encoded, $default = null); 27 | } 28 | -------------------------------------------------------------------------------- /app/Events/Subuser/Created.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Subuser; 11 | 12 | use Pterodactyl\Models\Subuser; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Created 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Subuser 23 | */ 24 | public $subuser; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Subuser $subuser) 30 | { 31 | $this->subuser = $subuser; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Events/Subuser/Deleted.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Subuser; 11 | 12 | use Pterodactyl\Models\Subuser; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Deleted 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Subuser 23 | */ 24 | public $subuser; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Subuser $subuser) 30 | { 31 | $this->subuser = $subuser; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2017_06_10_152951_add_external_id_to_users.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('external_id')->after('id')->nullable()->unique(); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down() 23 | { 24 | Schema::table('users', function (Blueprint $table) { 25 | $table->dropColumn('external_id'); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /resources/scripts/components/server/schedules/NewTaskButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Schedule } from '@/api/server/schedules/getServerSchedules'; 3 | import TaskDetailsModal from '@/components/server/schedules/TaskDetailsModal'; 4 | import { Button } from '@/components/elements/button/index'; 5 | 6 | interface Props { 7 | schedule: Schedule; 8 | } 9 | 10 | export default ({ schedule }: Props) => { 11 | const [visible, setVisible] = useState(false); 12 | 13 | return ( 14 | <> 15 | setVisible(false)} /> 16 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /app/Events/Subuser/Creating.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | namespace Pterodactyl\Events\Subuser; 11 | 12 | use Pterodactyl\Models\Subuser; 13 | use Illuminate\Queue\SerializesModels; 14 | 15 | class Creating 16 | { 17 | use SerializesModels; 18 | 19 | /** 20 | * The Eloquent model of the server. 21 | * 22 | * @var \Pterodactyl\Models\Subuser 23 | */ 24 | public $subuser; 25 | 26 | /** 27 | * Create a new event instance. 28 | */ 29 | public function __construct(Subuser $subuser) 30 | { 31 | $this->subuser = $subuser; 32 | } 33 | } 34 | --------------------------------------------------------------------------------