├── .babel-plugin-macrosrc.js ├── .editorconfig ├── .env.ci ├── .env.example ├── .eslintignore ├── .eslintrc.yml ├── .github ├── ISSUE_TEMPLATE │ └── bug-report.yml └── workflows │ ├── build.yml │ ├── release.yml │ └── tests.yml ├── .gitignore ├── .php-cs-fixer.dist.php ├── .yarnclean ├── BUILDING.md ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE.md ├── README.md ├── SECURITY.md ├── app ├── Console │ ├── Commands │ │ ├── Environment │ │ │ ├── AppSettingsCommand.php │ │ │ ├── DatabaseSettingsCommand.php │ │ │ └── EmailSettingsCommand.php │ │ ├── InfoCommand.php │ │ ├── Location │ │ │ ├── DeleteLocationCommand.php │ │ │ └── MakeLocationCommand.php │ │ ├── Maintenance │ │ │ ├── CleanServiceBackupFilesCommand.php │ │ │ └── PruneOrphanedBackupsCommand.php │ │ ├── Node │ │ │ ├── MakeNodeCommand.php │ │ │ ├── NodeConfigurationCommand.php │ │ │ └── NodeListCommand.php │ │ ├── Overrides │ │ │ ├── KeyGenerateCommand.php │ │ │ ├── SeedCommand.php │ │ │ └── UpCommand.php │ │ ├── Schedule │ │ │ └── ProcessRunnableCommand.php │ │ ├── Server │ │ │ └── BulkPowerActionCommand.php │ │ ├── UpgradeCommand.php │ │ └── User │ │ │ ├── DeleteUserCommand.php │ │ │ ├── DisableTwoFactorCommand.php │ │ │ └── MakeUserCommand.php │ ├── Kernel.php │ └── RequiresDatabaseMigrations.php ├── Contracts │ ├── Core │ │ └── ReceivesEvents.php │ ├── Criteria │ │ └── CriteriaInterface.php │ ├── Extensions │ │ └── HashidsInterface.php │ ├── Http │ │ └── ClientPermissionsRequest.php │ └── Repository │ │ ├── AllocationRepositoryInterface.php │ │ ├── ApiKeyRepositoryInterface.php │ │ ├── ApiPermissionRepositoryInterface.php │ │ ├── BillingRepositoryInterface.php │ │ ├── CreditsRepositoryInterface.php │ │ ├── DaemonKeyRepositoryInterface.php │ │ ├── DatabaseHostRepositoryInterface.php │ │ ├── DatabaseRepositoryInterface.php │ │ ├── EggRepositoryInterface.php │ │ ├── EggVariableRepositoryInterface.php │ │ ├── LocationRepositoryInterface.php │ │ ├── NestRepositoryInterface.php │ │ ├── NodeRepositoryInterface.php │ │ ├── PermissionRepositoryInterface.php │ │ ├── RepositoryInterface.php │ │ ├── ScheduleRepositoryInterface.php │ │ ├── ServerRepositoryInterface.php │ │ ├── ServerVariableRepositoryInterface.php │ │ ├── SessionRepositoryInterface.php │ │ ├── SettingsRepositoryInterface.php │ │ ├── SubuserRepositoryInterface.php │ │ ├── TaskRepositoryInterface.php │ │ └── UserRepositoryInterface.php ├── Events │ ├── ActivityLogged.php │ ├── Auth │ │ ├── FailedCaptcha.php │ │ ├── FailedPasswordReset.php │ │ └── ProvidedAuthenticationToken.php │ ├── Event.php │ ├── Server │ │ ├── Created.php │ │ ├── Creating.php │ │ ├── Deleted.php │ │ ├── Deleting.php │ │ ├── Installed.php │ │ ├── Saved.php │ │ ├── Saving.php │ │ ├── Updated.php │ │ └── Updating.php │ ├── Subuser │ │ ├── Created.php │ │ ├── Creating.php │ │ ├── Deleted.php │ │ └── Deleting.php │ └── User │ │ ├── Created.php │ │ ├── Creating.php │ │ ├── Deleted.php │ │ └── Deleting.php ├── Exceptions │ ├── AccountNotFoundException.php │ ├── AutoDeploymentException.php │ ├── DisplayException.php │ ├── Handler.php │ ├── Http │ │ ├── Base │ │ │ └── InvalidPasswordProvidedException.php │ │ ├── Connection │ │ │ └── DaemonConnectionException.php │ │ ├── HttpForbiddenException.php │ │ ├── Server │ │ │ ├── FileSizeTooLargeException.php │ │ │ ├── FileTypeNotEditableException.php │ │ │ └── ServerStateConflictException.php │ │ └── TwoFactorAuthRequiredException.php │ ├── Model │ │ └── DataValidationException.php │ ├── PterodactylException.php │ ├── Repository │ │ ├── Daemon │ │ │ └── InvalidPowerSignalException.php │ │ ├── DuplicateDatabaseNameException.php │ │ ├── RecordNotFoundException.php │ │ └── RepositoryException.php │ ├── Service │ │ ├── Allocation │ │ │ ├── AllocationDoesNotBelongToServerException.php │ │ │ ├── AutoAllocationNotEnabledException.php │ │ │ ├── CidrOutOfRangeException.php │ │ │ ├── InvalidPortMappingException.php │ │ │ ├── NoAutoAllocationSpaceAvailableException.php │ │ │ ├── PortOutOfRangeException.php │ │ │ ├── ServerUsingAllocationException.php │ │ │ └── TooManyPortsInRangeException.php │ │ ├── Backup │ │ │ ├── BackupLockedException.php │ │ │ └── TooManyBackupsException.php │ │ ├── Database │ │ │ ├── DatabaseClientFeatureNotEnabledException.php │ │ │ ├── NoSuitableDatabaseHostException.php │ │ │ └── TooManyDatabasesException.php │ │ ├── Deployment │ │ │ ├── NoViableAllocationException.php │ │ │ └── NoViableNodeException.php │ │ ├── Egg │ │ │ ├── BadJsonFormatException.php │ │ │ ├── HasChildrenException.php │ │ │ ├── InvalidCopyFromException.php │ │ │ ├── NoParentConfigurationFoundException.php │ │ │ └── Variable │ │ │ │ ├── BadValidationRuleException.php │ │ │ │ └── ReservedVariableNameException.php │ │ ├── HasActiveServersException.php │ │ ├── Helper │ │ │ └── CdnVersionFetchingException.php │ │ ├── InvalidFileUploadException.php │ │ ├── Location │ │ │ └── HasActiveNodesException.php │ │ ├── Node │ │ │ └── ConfigurationNotPersistedException.php │ │ ├── Schedule │ │ │ └── Task │ │ │ │ └── TaskIntervalTooLongException.php │ │ ├── Server │ │ │ └── RequiredVariableMissingException.php │ │ ├── ServiceLimitExceededException.php │ │ ├── Subuser │ │ │ ├── ServerSubuserExistsException.php │ │ │ └── UserIsServerOwnerException.php │ │ └── User │ │ │ └── TwoFactorAuthenticationTokenInvalid.php │ └── Transformer │ │ └── InvalidTransformerLevelException.php ├── Extensions │ ├── Backups │ │ └── BackupManager.php │ ├── DynamicDatabaseConnection.php │ ├── Facades │ │ └── Theme.php │ ├── Hashids.php │ ├── Illuminate │ │ ├── Database │ │ │ └── Eloquent │ │ │ │ └── Builder.php │ │ └── Events │ │ │ └── Contracts │ │ │ └── SubscribesToEvents.php │ ├── Laravel │ │ └── Sanctum │ │ │ └── NewAccessToken.php │ ├── Lcobucci │ │ └── JWT │ │ │ └── Encoding │ │ │ └── TimestampDates.php │ ├── League │ │ └── Fractal │ │ │ └── Serializers │ │ │ └── PterodactylSerializer.php │ ├── Spatie │ │ └── Fractalistic │ │ │ └── Fractal.php │ └── Themes │ │ └── Theme.php ├── Facades │ ├── Activity.php │ ├── LogBatch.php │ └── LogTarget.php ├── Helpers │ ├── Time.php │ └── Utilities.php ├── Http │ ├── Controllers │ │ ├── Admin │ │ │ ├── ApiController.php │ │ │ ├── BaseController.php │ │ │ ├── BillingController.php │ │ │ ├── Credits │ │ │ │ ├── ConfigController.php │ │ │ │ ├── PaymentsController.php │ │ │ │ └── StoreController.php │ │ │ ├── DatabaseController.php │ │ │ ├── LocationController.php │ │ │ ├── LogsController.php │ │ │ ├── MountController.php │ │ │ ├── Nests │ │ │ │ ├── EggController.php │ │ │ │ ├── EggScriptController.php │ │ │ │ ├── EggShareController.php │ │ │ │ ├── EggVariableController.php │ │ │ │ └── NestController.php │ │ │ ├── NodeAutoDeployController.php │ │ │ ├── Nodes │ │ │ │ ├── NodeController.php │ │ │ │ ├── NodeViewController.php │ │ │ │ └── SystemInformationController.php │ │ │ ├── NodesController.php │ │ │ ├── Servers │ │ │ │ ├── CreateServerController.php │ │ │ │ ├── ServerController.php │ │ │ │ ├── ServerTransferController.php │ │ │ │ └── ServerViewController.php │ │ │ ├── ServersController.php │ │ │ ├── Settings │ │ │ │ ├── AdvancedController.php │ │ │ │ ├── IndexController.php │ │ │ │ └── MailController.php │ │ │ └── UserController.php │ │ ├── Api │ │ │ ├── Application │ │ │ │ ├── ApplicationApiController.php │ │ │ │ ├── CreditsController.php │ │ │ │ ├── Locations │ │ │ │ │ └── LocationController.php │ │ │ │ ├── Nests │ │ │ │ │ ├── EggController.php │ │ │ │ │ └── NestController.php │ │ │ │ ├── Nodes │ │ │ │ │ ├── AllocationController.php │ │ │ │ │ ├── NodeConfigurationController.php │ │ │ │ │ ├── NodeController.php │ │ │ │ │ └── NodeDeploymentController.php │ │ │ │ ├── Servers │ │ │ │ │ ├── DatabaseController.php │ │ │ │ │ ├── ExternalServerController.php │ │ │ │ │ ├── ServerController.php │ │ │ │ │ ├── ServerDetailsController.php │ │ │ │ │ ├── ServerManagementController.php │ │ │ │ │ └── StartupController.php │ │ │ │ └── Users │ │ │ │ │ ├── ExternalUserController.php │ │ │ │ │ └── UserController.php │ │ │ ├── Client │ │ │ │ ├── AccountController.php │ │ │ │ ├── ActivityLogController.php │ │ │ │ ├── ApiKeyController.php │ │ │ │ ├── ClientApiController.php │ │ │ │ ├── ClientController.php │ │ │ │ ├── Credits │ │ │ │ │ ├── PaymentController.php │ │ │ │ │ ├── ResourceController.php │ │ │ │ │ └── ServerController.php │ │ │ │ ├── NotificationController.php │ │ │ │ ├── SSHKeyController.php │ │ │ │ ├── Servers │ │ │ │ │ ├── AuditLogsController.php │ │ │ │ │ ├── BackupController.php │ │ │ │ │ ├── CommandController.php │ │ │ │ │ ├── DatabaseController.php │ │ │ │ │ ├── FileController.php │ │ │ │ │ ├── FileUploadController.php │ │ │ │ │ ├── NetworkAllocationController.php │ │ │ │ │ ├── PowerController.php │ │ │ │ │ ├── ResourceUtilizationController.php │ │ │ │ │ ├── ScheduleController.php │ │ │ │ │ ├── ScheduleTaskController.php │ │ │ │ │ ├── ServerController.php │ │ │ │ │ ├── SettingsController.php │ │ │ │ │ ├── StartupController.php │ │ │ │ │ ├── SubuserController.php │ │ │ │ │ └── WebsocketController.php │ │ │ │ ├── TwoFactorController.php │ │ │ │ └── WebauthnController.php │ │ │ └── Remote │ │ │ │ ├── Backups │ │ │ │ ├── BackupRemoteUploadController.php │ │ │ │ └── BackupStatusController.php │ │ │ │ ├── EggInstallController.php │ │ │ │ ├── Servers │ │ │ │ ├── ServerDetailsController.php │ │ │ │ ├── ServerInstallController.php │ │ │ │ └── ServerTransferController.php │ │ │ │ └── SftpAuthenticationController.php │ │ ├── Auth │ │ │ ├── AbstractLoginController.php │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginCheckpointController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ ├── ResetPasswordController.php │ │ │ └── WebauthnController.php │ │ ├── Base │ │ │ ├── IndexController.php │ │ │ └── LocaleController.php │ │ └── Controller.php │ ├── Kernel.php │ ├── Middleware │ │ ├── AccountActivitySubject.php │ │ ├── Admin │ │ │ └── Servers │ │ │ │ └── ServerInstalled.php │ │ ├── AdminAuthenticate.php │ │ ├── Api │ │ │ ├── Application │ │ │ │ └── AuthenticateApplicationUser.php │ │ │ ├── AuthenticateIPAccess.php │ │ │ ├── Client │ │ │ │ ├── RequireClientApiKey.php │ │ │ │ ├── Server │ │ │ │ │ ├── AuthenticateServerAccess.php │ │ │ │ │ └── ResourceBelongsToServer.php │ │ │ │ └── SubstituteClientBindings.php │ │ │ ├── Daemon │ │ │ │ └── DaemonAuthenticate.php │ │ │ └── IsValidJson.php │ │ ├── EncryptCookies.php │ │ ├── EnsureStatefulRequests.php │ │ ├── LanguageMiddleware.php │ │ ├── MaintenanceMiddleware.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── RequireTwoFactorAuthentication.php │ │ ├── ServerActivitySubject.php │ │ ├── TrimStrings.php │ │ ├── VerifyCsrfToken.php │ │ └── VerifyReCaptcha.php │ ├── Requests │ │ ├── Admin │ │ │ ├── AdminFormRequest.php │ │ │ ├── Api │ │ │ │ └── StoreApplicationApiKeyRequest.php │ │ │ ├── BaseFormRequest.php │ │ │ ├── BillingFormRequest.php │ │ │ ├── Credits │ │ │ │ ├── ConfigFormRequest.php │ │ │ │ ├── PaymentsFormRequest.php │ │ │ │ └── StoreFormRequest.php │ │ │ ├── DatabaseHostFormRequest.php │ │ │ ├── Egg │ │ │ │ ├── EggFormRequest.php │ │ │ │ ├── EggImportFormRequest.php │ │ │ │ ├── EggScriptFormRequest.php │ │ │ │ └── EggVariableFormRequest.php │ │ │ ├── LocationFormRequest.php │ │ │ ├── MountFormRequest.php │ │ │ ├── Nest │ │ │ │ └── StoreNestFormRequest.php │ │ │ ├── Node │ │ │ │ ├── AllocationAliasFormRequest.php │ │ │ │ ├── AllocationFormRequest.php │ │ │ │ └── NodeFormRequest.php │ │ │ ├── ServerFormRequest.php │ │ │ ├── Servers │ │ │ │ └── Databases │ │ │ │ │ └── StoreServerDatabaseRequest.php │ │ │ ├── Settings │ │ │ │ ├── AdvancedSettingsFormRequest.php │ │ │ │ ├── BaseSettingsFormRequest.php │ │ │ │ └── MailSettingsFormRequest.php │ │ │ └── Users │ │ │ │ ├── UserFormRequest.php │ │ │ │ └── UserResourceFormRequest.php │ │ ├── Api │ │ │ ├── Application │ │ │ │ ├── Allocations │ │ │ │ │ ├── DeleteAllocationRequest.php │ │ │ │ │ ├── GetAllocationsRequest.php │ │ │ │ │ └── StoreAllocationRequest.php │ │ │ │ ├── ApplicationApiRequest.php │ │ │ │ ├── CreditsRequest.php │ │ │ │ ├── Locations │ │ │ │ │ ├── DeleteLocationRequest.php │ │ │ │ │ ├── GetLocationRequest.php │ │ │ │ │ ├── GetLocationsRequest.php │ │ │ │ │ ├── StoreLocationRequest.php │ │ │ │ │ └── UpdateLocationRequest.php │ │ │ │ ├── Nests │ │ │ │ │ ├── Eggs │ │ │ │ │ │ ├── GetEggRequest.php │ │ │ │ │ │ └── GetEggsRequest.php │ │ │ │ │ └── GetNestsRequest.php │ │ │ │ ├── Nodes │ │ │ │ │ ├── DeleteNodeRequest.php │ │ │ │ │ ├── GetDeployableNodesRequest.php │ │ │ │ │ ├── GetNodeRequest.php │ │ │ │ │ ├── GetNodesRequest.php │ │ │ │ │ ├── StoreNodeRequest.php │ │ │ │ │ └── UpdateNodeRequest.php │ │ │ │ ├── Servers │ │ │ │ │ ├── Databases │ │ │ │ │ │ ├── GetServerDatabaseRequest.php │ │ │ │ │ │ ├── GetServerDatabasesRequest.php │ │ │ │ │ │ ├── ServerDatabaseWriteRequest.php │ │ │ │ │ │ └── StoreServerDatabaseRequest.php │ │ │ │ │ ├── GetExternalServerRequest.php │ │ │ │ │ ├── GetServerRequest.php │ │ │ │ │ ├── GetServersRequest.php │ │ │ │ │ ├── ServerWriteRequest.php │ │ │ │ │ ├── StoreServerRequest.php │ │ │ │ │ ├── UpdateServerBuildConfigurationRequest.php │ │ │ │ │ ├── UpdateServerDetailsRequest.php │ │ │ │ │ └── UpdateServerStartupRequest.php │ │ │ │ └── Users │ │ │ │ │ ├── DeleteUserRequest.php │ │ │ │ │ ├── GetExternalUserRequest.php │ │ │ │ │ ├── GetUsersRequest.php │ │ │ │ │ ├── StoreUserRequest.php │ │ │ │ │ └── UpdateUserRequest.php │ │ │ ├── Client │ │ │ │ ├── Account │ │ │ │ │ ├── StoreApiKeyRequest.php │ │ │ │ │ ├── StoreSSHKeyRequest.php │ │ │ │ │ ├── UpdateEmailRequest.php │ │ │ │ │ ├── UpdatePasswordRequest.php │ │ │ │ │ └── UpdateUsernameRequest.php │ │ │ │ ├── ClientApiRequest.php │ │ │ │ ├── GetServersRequest.php │ │ │ │ ├── Servers │ │ │ │ │ ├── AuditLogs │ │ │ │ │ │ └── GetAuditLogsRequest.php │ │ │ │ │ ├── Backups │ │ │ │ │ │ └── StoreBackupRequest.php │ │ │ │ │ ├── Databases │ │ │ │ │ │ ├── DeleteDatabaseRequest.php │ │ │ │ │ │ ├── GetDatabasesRequest.php │ │ │ │ │ │ ├── RotatePasswordRequest.php │ │ │ │ │ │ └── StoreDatabaseRequest.php │ │ │ │ │ ├── Files │ │ │ │ │ │ ├── ChmodFilesRequest.php │ │ │ │ │ │ ├── CompressFilesRequest.php │ │ │ │ │ │ ├── CopyFileRequest.php │ │ │ │ │ │ ├── CreateFolderRequest.php │ │ │ │ │ │ ├── DecompressFilesRequest.php │ │ │ │ │ │ ├── DeleteFileRequest.php │ │ │ │ │ │ ├── DownloadFileRequest.php │ │ │ │ │ │ ├── GetFileContentsRequest.php │ │ │ │ │ │ ├── ListFilesRequest.php │ │ │ │ │ │ ├── PullFileRequest.php │ │ │ │ │ │ ├── RenameFileRequest.php │ │ │ │ │ │ ├── UploadFileRequest.php │ │ │ │ │ │ └── WriteFileContentRequest.php │ │ │ │ │ ├── GetServerRequest.php │ │ │ │ │ ├── Network │ │ │ │ │ │ ├── DeleteAllocationRequest.php │ │ │ │ │ │ ├── GetNetworkRequest.php │ │ │ │ │ │ ├── NewAllocationRequest.php │ │ │ │ │ │ ├── SetPrimaryAllocationRequest.php │ │ │ │ │ │ └── UpdateAllocationRequest.php │ │ │ │ │ ├── Schedules │ │ │ │ │ │ ├── DeleteScheduleRequest.php │ │ │ │ │ │ ├── StoreScheduleRequest.php │ │ │ │ │ │ ├── StoreTaskRequest.php │ │ │ │ │ │ ├── TriggerScheduleRequest.php │ │ │ │ │ │ ├── UpdateScheduleRequest.php │ │ │ │ │ │ └── ViewScheduleRequest.php │ │ │ │ │ ├── SendCommandRequest.php │ │ │ │ │ ├── SendPowerRequest.php │ │ │ │ │ ├── Settings │ │ │ │ │ │ ├── ReinstallServerRequest.php │ │ │ │ │ │ ├── RenameServerRequest.php │ │ │ │ │ │ └── SetDockerImageRequest.php │ │ │ │ │ ├── Startup │ │ │ │ │ │ ├── GetStartupRequest.php │ │ │ │ │ │ └── UpdateStartupVariableRequest.php │ │ │ │ │ └── Subusers │ │ │ │ │ │ ├── DeleteSubuserRequest.php │ │ │ │ │ │ ├── GetSubuserRequest.php │ │ │ │ │ │ ├── StoreSubuserRequest.php │ │ │ │ │ │ ├── SubuserRequest.php │ │ │ │ │ │ └── UpdateSubuserRequest.php │ │ │ │ └── StoreRequest.php │ │ │ └── Remote │ │ │ │ ├── AuthenticateWebsocketDetailsRequest.php │ │ │ │ ├── InstallationDataRequest.php │ │ │ │ ├── ReportBackupCompleteRequest.php │ │ │ │ └── SftpAuthenticationFormRequest.php │ │ ├── Auth │ │ │ ├── LoginCheckpointRequest.php │ │ │ ├── LoginRequest.php │ │ │ ├── RegisterRequest.php │ │ │ └── ResetPasswordRequest.php │ │ └── FrontendUserFormRequest.php │ ├── Resources │ │ └── Wings │ │ │ └── ServerConfigurationCollection.php │ └── ViewComposers │ │ └── AssetComposer.php ├── Jobs │ ├── Job.php │ └── Schedule │ │ └── RunTaskJob.php ├── Listeners │ └── Auth │ │ ├── AuthenticationListener.php │ │ ├── PasswordResetListener.php │ │ └── TwoFactorListener.php ├── Models │ ├── APILog.php │ ├── ActivityLog.php │ ├── ActivityLogSubject.php │ ├── Allocation.php │ ├── ApiKey.php │ ├── AuditLog.php │ ├── Backup.php │ ├── Billing.php │ ├── Credits.php │ ├── Database.php │ ├── DatabaseHost.php │ ├── Egg.php │ ├── EggMount.php │ ├── EggVariable.php │ ├── Filters │ │ ├── AdminServerFilter.php │ │ └── MultiFieldServerFilter.php │ ├── Location.php │ ├── Model.php │ ├── Mount.php │ ├── MountNode.php │ ├── MountServer.php │ ├── Nest.php │ ├── Node.php │ ├── Notification.php │ ├── Objects │ │ └── DeploymentObject.php │ ├── Permission.php │ ├── RecoveryToken.php │ ├── Schedule.php │ ├── Server.php │ ├── ServerTransfer.php │ ├── ServerVariable.php │ ├── Session.php │ ├── Setting.php │ ├── Subuser.php │ ├── Task.php │ ├── TaskLog.php │ ├── Traits │ │ └── HasAccessTokens.php │ ├── User.php │ ├── UserSSHKey.php │ └── WebauthnKey.php ├── Notifications │ ├── AccountCreated.php │ ├── AddedToServer.php │ ├── MailTested.php │ ├── RemovedFromServer.php │ ├── SendPasswordReset.php │ └── ServerInstalled.php ├── Observers │ ├── EggVariableObserver.php │ ├── ServerObserver.php │ ├── SubuserObserver.php │ └── UserObserver.php ├── Policies │ ├── .gitkeep │ └── ServerPolicy.php ├── Providers │ ├── ActivityLogServiceProvider.php │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BackupsServiceProvider.php │ ├── BladeServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ ├── HashidsServiceProvider.php │ ├── RepositoryServiceProvider.php │ ├── RouteServiceProvider.php │ ├── SettingsServiceProvider.php │ └── ViewComposerServiceProvider.php ├── Repositories │ ├── Eloquent │ │ ├── AllocationRepository.php │ │ ├── ApiKeyRepository.php │ │ ├── BackupRepository.php │ │ ├── BillingRepository.php │ │ ├── CreditsRepository.php │ │ ├── DatabaseHostRepository.php │ │ ├── DatabaseRepository.php │ │ ├── EggRepository.php │ │ ├── EggVariableRepository.php │ │ ├── EloquentRepository.php │ │ ├── LocationRepository.php │ │ ├── MountRepository.php │ │ ├── NestRepository.php │ │ ├── NodeRepository.php │ │ ├── PermissionRepository.php │ │ ├── RecoveryTokenRepository.php │ │ ├── ScheduleRepository.php │ │ ├── ServerRepository.php │ │ ├── ServerVariableRepository.php │ │ ├── SessionRepository.php │ │ ├── SettingsRepository.php │ │ ├── SubuserRepository.php │ │ ├── TaskRepository.php │ │ └── UserRepository.php │ ├── Repository.php │ └── Wings │ │ ├── DaemonBackupRepository.php │ │ ├── DaemonCommandRepository.php │ │ ├── DaemonConfigurationRepository.php │ │ ├── DaemonFileRepository.php │ │ ├── DaemonPowerRepository.php │ │ ├── DaemonRepository.php │ │ ├── DaemonServerRepository.php │ │ └── DaemonTransferRepository.php ├── Rules │ └── Username.php ├── Services │ ├── Acl │ │ └── Api │ │ │ └── AdminAcl.php │ ├── Activity │ │ ├── AcitvityLogBatchService.php │ │ ├── ActivityLogService.php │ │ └── ActivityLogTargetableService.php │ ├── Allocations │ │ ├── AllocationDeletionService.php │ │ ├── AssignmentService.php │ │ └── FindAssignableAllocationService.php │ ├── Api │ │ └── KeyCreationService.php │ ├── Backups │ │ ├── DeleteBackupService.php │ │ ├── DownloadLinkService.php │ │ └── InitiateBackupService.php │ ├── Databases │ │ ├── DatabaseManagementService.php │ │ ├── DatabasePasswordService.php │ │ ├── DeployServerDatabaseService.php │ │ └── Hosts │ │ │ ├── HostCreationService.php │ │ │ ├── HostDeletionService.php │ │ │ └── HostUpdateService.php │ ├── Deployment │ │ ├── AllocationSelectionService.php │ │ └── FindViableNodesService.php │ ├── Eggs │ │ ├── EggConfigurationService.php │ │ ├── EggCreationService.php │ │ ├── EggDeletionService.php │ │ ├── EggParserService.php │ │ ├── EggUpdateService.php │ │ ├── Scripts │ │ │ └── InstallScriptService.php │ │ ├── Sharing │ │ │ ├── EggExporterService.php │ │ │ ├── EggImporterService.php │ │ │ └── EggUpdateImporterService.php │ │ └── Variables │ │ │ ├── VariableCreationService.php │ │ │ └── VariableUpdateService.php │ ├── Helpers │ │ ├── ApiAllowedIpsValidatorService.php │ │ ├── AssetHashService.php │ │ └── SoftwareVersionService.php │ ├── Locations │ │ ├── LocationCreationService.php │ │ ├── LocationDeletionService.php │ │ └── LocationUpdateService.php │ ├── Nests │ │ ├── NestCreationService.php │ │ ├── NestDeletionService.php │ │ └── NestUpdateService.php │ ├── Nodes │ │ ├── NodeCreationService.php │ │ ├── NodeDeletionService.php │ │ ├── NodeJWTService.php │ │ └── NodeUpdateService.php │ ├── Schedules │ │ └── ProcessScheduleService.php │ ├── Servers │ │ ├── BuildModificationService.php │ │ ├── DetailsModificationService.php │ │ ├── EnvironmentService.php │ │ ├── GetUserPermissionsService.php │ │ ├── ReinstallServerService.php │ │ ├── ServerConfigurationStructureService.php │ │ ├── ServerCreationService.php │ │ ├── ServerDeletionService.php │ │ ├── StartupCommandService.php │ │ ├── StartupModificationService.php │ │ ├── SuspensionService.php │ │ ├── TransferService.php │ │ └── VariableValidatorService.php │ ├── Subusers │ │ └── SubuserCreationService.php │ └── Users │ │ ├── ToggleTwoFactorService.php │ │ ├── TwoFactorSetupService.php │ │ ├── UserCreationService.php │ │ ├── UserDeletionService.php │ │ └── UserUpdateService.php ├── Traits │ ├── Commands │ │ └── EnvironmentWriterTrait.php │ ├── Controllers │ │ ├── JavascriptInjection.php │ │ └── PlainJavascriptInjection.php │ ├── Helpers │ │ └── AvailableLanguages.php │ └── Services │ │ ├── HasUserLevels.php │ │ ├── ReturnsUpdatedModels.php │ │ └── ValidatesValidationRules.php ├── Transformers │ └── Api │ │ ├── Application │ │ ├── AllocationTransformer.php │ │ ├── BaseTransformer.php │ │ ├── DatabaseHostTransformer.php │ │ ├── EggTransformer.php │ │ ├── EggVariableTransformer.php │ │ ├── LocationTransformer.php │ │ ├── NestTransformer.php │ │ ├── NodeTransformer.php │ │ ├── ServerDatabaseTransformer.php │ │ ├── ServerTransformer.php │ │ ├── ServerVariableTransformer.php │ │ ├── SubuserTransformer.php │ │ └── UserTransformer.php │ │ └── Client │ │ ├── AccountTransformer.php │ │ ├── ActivityLogTransformer.php │ │ ├── AllocationTransformer.php │ │ ├── ApiKeyTransformer.php │ │ ├── AuditLogTransformer.php │ │ ├── BackupTransformer.php │ │ ├── BaseClientTransformer.php │ │ ├── DatabaseTransformer.php │ │ ├── EggTransformer.php │ │ ├── EggVariableTransformer.php │ │ ├── FileObjectTransformer.php │ │ ├── NotificationTransformer.php │ │ ├── ScheduleTransformer.php │ │ ├── ServerTransformer.php │ │ ├── StatsTransformer.php │ │ ├── SubuserTransformer.php │ │ ├── TaskTransformer.php │ │ ├── UserSSHKeyTransformer.php │ │ ├── UserTransformer.php │ │ └── WebauthnKeyTransformer.php └── helpers.php ├── artisan ├── babel.config.js ├── bootstrap ├── app.php ├── cache │ └── .gitignore └── tests.php ├── composer.json ├── composer.lock ├── config ├── activity.php ├── app.php ├── auth.php ├── backups.php ├── broadcasting.php ├── cache.php ├── compile.php ├── cors.php ├── database.php ├── egg_features │ └── eula.php ├── filesystems.php ├── fractal.php ├── hashids.php ├── hashing.php ├── http.php ├── ide-helper.php ├── javascript.php ├── logging.php ├── mail.php ├── prologue │ └── alerts.php ├── pterodactyl.php ├── queue.php ├── recaptcha.php ├── sanctum.php ├── services.php ├── session.php ├── trustedproxy.php ├── view.php ├── vue-i18n-generator.php └── webauthn.php ├── database ├── .gitignore ├── Factories │ ├── AllocationFactory.php │ ├── ApiKeyFactory.php │ ├── BackupFactory.php │ ├── DatabaseFactory.php │ ├── DatabaseHostFactory.php │ ├── EggFactory.php │ ├── EggVariableFactory.php │ ├── LocationFactory.php │ ├── NestFactory.php │ ├── NodeFactory.php │ ├── ScheduleFactory.php │ ├── ServerFactory.php │ ├── SubuserFactory.php │ ├── TaskFactory.php │ ├── UserFactory.php │ └── UserSSHKeyFactory.php ├── Seeders │ ├── .gitkeep │ ├── DatabaseSeeder.php │ ├── EggSeeder.php │ ├── NestSeeder.php │ └── eggs │ │ ├── jexactyl │ │ └── multi-egg.json │ │ ├── minecraft │ │ ├── egg-bungeecord.json │ │ ├── egg-forge-minecraft.json │ │ ├── egg-paper.json │ │ ├── egg-sponge--sponge-vanilla.json │ │ └── egg-vanilla-minecraft.json │ │ └── source-engine │ │ └── egg-team-fortress2.json └── migrations │ ├── 2016_01_23_195641_add_allocations_table.php │ ├── 2016_01_23_195851_add_api_keys.php │ ├── 2016_01_23_200044_add_api_permissions.php │ ├── 2016_01_23_200159_add_downloads.php │ ├── 2016_01_23_200421_create_failed_jobs_table.php │ ├── 2016_01_23_200440_create_jobs_table.php │ ├── 2016_01_23_200528_add_locations.php │ ├── 2016_01_23_200648_add_nodes.php │ ├── 2016_01_23_201433_add_password_resets.php │ ├── 2016_01_23_201531_add_permissions.php │ ├── 2016_01_23_201649_add_server_variables.php │ ├── 2016_01_23_201748_add_servers.php │ ├── 2016_01_23_202544_add_service_options.php │ ├── 2016_01_23_202731_add_service_varibles.php │ ├── 2016_01_23_202943_add_services.php │ ├── 2016_01_23_203119_create_settings_table.php │ ├── 2016_01_23_203150_add_subusers.php │ ├── 2016_01_23_203159_add_users.php │ ├── 2016_01_23_203947_create_sessions_table.php │ ├── 2016_01_25_234418_rename_permissions_column.php │ ├── 2016_02_07_172148_add_databases_tables.php │ ├── 2016_02_07_181319_add_database_servers_table.php │ ├── 2016_02_13_154306_add_service_option_default_startup.php │ ├── 2016_02_20_155318_add_unique_service_field.php │ ├── 2016_02_27_163411_add_tasks_table.php │ ├── 2016_02_27_163447_add_tasks_log_table.php │ ├── 2016_03_18_155649_add_nullable_field_lastrun.php │ ├── 2016_08_30_212718_add_ip_alias.php │ ├── 2016_08_30_213301_modify_ip_storage_method.php │ ├── 2016_09_01_193520_add_suspension_for_servers.php │ ├── 2016_09_01_211924_remove_active_column.php │ ├── 2016_09_02_190647_add_sftp_password_storage.php │ ├── 2016_09_04_171338_update_jobs_tables.php │ ├── 2016_09_04_172028_update_failed_jobs_table.php │ ├── 2016_09_04_182835_create_notifications_table.php │ ├── 2016_09_07_163017_add_unique_identifier.php │ ├── 2016_09_14_145945_allow_longer_regex_field.php │ ├── 2016_09_17_194246_add_docker_image_column.php │ ├── 2016_09_21_165554_update_servers_column_name.php │ ├── 2016_09_29_213518_rename_double_insurgency.php │ ├── 2016_10_07_152117_build_api_log_table.php │ ├── 2016_10_14_164802_update_api_keys.php │ ├── 2016_10_23_181719_update_misnamed_bungee.php │ ├── 2016_10_23_193810_add_foreign_keys_servers.php │ ├── 2016_10_23_201624_add_foreign_allocations.php │ ├── 2016_10_23_202222_add_foreign_api_keys.php │ ├── 2016_10_23_202703_add_foreign_api_permissions.php │ ├── 2016_10_23_202953_add_foreign_database_servers.php │ ├── 2016_10_23_203105_add_foreign_databases.php │ ├── 2016_10_23_203335_add_foreign_nodes.php │ ├── 2016_10_23_203522_add_foreign_permissions.php │ ├── 2016_10_23_203857_add_foreign_server_variables.php │ ├── 2016_10_23_204157_add_foreign_service_options.php │ ├── 2016_10_23_204321_add_foreign_service_variables.php │ ├── 2016_10_23_204454_add_foreign_subusers.php │ ├── 2016_10_23_204610_add_foreign_tasks.php │ ├── 2016_11_04_000949_add_ark_service_option_fixed.php │ ├── 2016_11_11_220649_add_pack_support.php │ ├── 2016_11_11_231731_set_service_name_unique.php │ ├── 2016_11_27_142519_add_pack_column.php │ ├── 2016_12_01_173018_add_configurable_upload_limit.php │ ├── 2016_12_02_185206_correct_service_variables.php │ ├── 2017_01_03_150436_fix_misnamed_option_tag.php │ ├── 2017_01_07_154228_create_node_configuration_tokens_table.php │ ├── 2017_01_12_135449_add_more_user_data.php │ ├── 2017_02_02_175548_UpdateColumnNames.php │ ├── 2017_02_03_140948_UpdateNodesTable.php │ ├── 2017_02_03_155554_RenameColumns.php │ ├── 2017_02_05_164123_AdjustColumnNames.php │ ├── 2017_02_05_164516_AdjustColumnNamesForServicePacks.php │ ├── 2017_02_09_174834_SetupPermissionsPivotTable.php │ ├── 2017_02_10_171858_UpdateAPIKeyColumnNames.php │ ├── 2017_03_03_224254_UpdateNodeConfigTokensColumns.php │ ├── 2017_03_05_212803_DeleteServiceExecutableOption.php │ ├── 2017_03_10_162934_AddNewServiceOptionsColumns.php │ ├── 2017_03_10_173607_MigrateToNewServiceSystem.php │ ├── 2017_03_11_215455_ChangeServiceVariablesValidationRules.php │ ├── 2017_03_12_150648_MoveFunctionsFromFileToDatabase.php │ ├── 2017_03_14_175631_RenameServicePacksToSingluarPacks.php │ ├── 2017_03_14_200326_AddLockedStatusToTable.php │ ├── 2017_03_16_181109_ReOrganizeDatabaseServersToDatabaseHost.php │ ├── 2017_03_16_181515_CleanupDatabasesDatabase.php │ ├── 2017_03_18_204953_AddForeignKeyToPacks.php │ ├── 2017_03_31_221948_AddServerDescriptionColumn.php │ ├── 2017_04_02_163232_DropDeletedAtColumnFromServers.php │ ├── 2017_04_15_125021_UpgradeTaskSystem.php │ ├── 2017_04_20_171943_AddScriptsToServiceOptions.php │ ├── 2017_04_21_151432_AddServiceScriptTrackingToServers.php │ ├── 2017_04_27_145300_AddCopyScriptFromColumn.php │ ├── 2017_04_27_223629_AddAbilityToDefineConnectionOverSSLWithDaemonBehindProxy.php │ ├── 2017_05_01_141528_DeleteDownloadTable.php │ ├── 2017_05_01_141559_DeleteNodeConfigurationTable.php │ ├── 2017_06_10_152951_add_external_id_to_users.php │ ├── 2017_06_25_133923_ChangeForeignKeyToBeOnCascadeDelete.php │ ├── 2017_07_08_152806_ChangeUserPermissionsToDeleteOnUserDeletion.php │ ├── 2017_07_08_154416_SetAllocationToReferenceNullOnServerDelete.php │ ├── 2017_07_08_154650_CascadeDeletionWhenAServerOrVariableIsDeleted.php │ ├── 2017_07_24_194433_DeleteTaskWhenParentServerIsDeleted.php │ ├── 2017_08_05_115800_CascadeNullValuesForDatabaseHostWhenNodeIsDeleted.php │ ├── 2017_08_05_144104_AllowNegativeValuesForOverallocation.php │ ├── 2017_08_05_174811_SetAllocationUnqiueUsingMultipleFields.php │ ├── 2017_08_15_214555_CascadeDeletionWhenAParentServiceIsDeleted.php │ ├── 2017_08_18_215428_RemovePackWhenParentServiceOptionIsDeleted.php │ ├── 2017_09_10_225749_RenameTasksTableForStructureRefactor.php │ ├── 2017_09_10_225941_CreateSchedulesTable.php │ ├── 2017_09_10_230309_CreateNewTasksTableForSchedules.php │ ├── 2017_09_11_002938_TransferOldTasksToNewScheduler.php │ ├── 2017_09_13_211810_UpdateOldPermissionsToPointToNewScheduleSystem.php │ ├── 2017_09_23_170933_CreateDaemonKeysTable.php │ ├── 2017_09_23_173628_RemoveDaemonSecretFromServersTable.php │ ├── 2017_09_23_185022_RemoveDaemonSecretFromSubusersTable.php │ ├── 2017_10_02_202000_ChangeServicesToUseAMoreUniqueIdentifier.php │ ├── 2017_10_02_202007_ChangeToABetterUniqueServiceConfiguration.php │ ├── 2017_10_03_233202_CascadeDeletionWhenServiceOptionIsDeleted.php │ ├── 2017_10_06_214026_ServicesToNestsConversion.php │ ├── 2017_10_06_214053_ServiceOptionsToEggsConversion.php │ ├── 2017_10_06_215741_ServiceVariablesToEggVariablesConversion.php │ ├── 2017_10_24_222238_RemoveLegacySFTPInformation.php │ ├── 2017_11_11_161922_Add2FaLastAuthorizationTimeColumn.php │ ├── 2017_11_19_122708_MigratePubPrivFormatToSingleKey.php │ ├── 2017_12_04_184012_DropAllocationsWhenNodeIsDeleted.php │ ├── 2017_12_12_220426_MigrateSettingsTableToNewFormat.php │ ├── 2018_01_01_122821_AllowNegativeValuesForServerSwap.php │ ├── 2018_01_11_213943_AddApiKeyPermissionColumns.php │ ├── 2018_01_13_142012_SetupTableForKeyEncryption.php │ ├── 2018_01_13_145209_AddLastUsedAtColumn.php │ ├── 2018_02_04_145617_AllowTextInUserExternalId.php │ ├── 2018_02_10_151150_remove_unique_index_on_external_id_column.php │ ├── 2018_02_17_134254_ensure_unique_allocation_id_on_servers_table.php │ ├── 2018_02_24_112356_add_external_id_column_to_servers_table.php │ ├── 2018_02_25_160152_remove_default_null_value_on_table.php │ ├── 2018_02_25_160604_define_unique_index_on_users_external_id.php │ ├── 2018_03_01_192831_add_database_and_port_limit_columns_to_servers_table.php │ ├── 2018_03_15_124536_add_description_to_nodes.php │ ├── 2018_05_04_123826_add_maintenance_to_nodes.php │ ├── 2018_09_03_143756_allow_egg_variables_to_have_longer_values.php │ ├── 2018_09_03_144005_allow_server_variables_to_have_longer_values.php │ ├── 2019_03_02_142328_set_allocation_limit_default_null.php │ ├── 2019_03_02_151321_fix_unique_index_to_account_for_host.php │ ├── 2019_03_29_163611_add_webauthn.php │ ├── 2020_03_22_163911_merge_permissions_table_into_subusers.php │ ├── 2020_03_22_164814_drop_permissions_table.php │ ├── 2020_04_03_203624_add_threads_column_to_servers_table.php │ ├── 2020_04_03_230614_create_backups_table.php │ ├── 2020_04_04_131016_add_table_server_transfers.php │ ├── 2020_04_10_141024_store_node_tokens_as_encrypted_value.php │ ├── 2020_04_17_203438_allow_nullable_descriptions.php │ ├── 2020_04_22_055500_add_max_connections_column.php │ ├── 2020_04_26_111208_add_backup_limit_to_servers.php │ ├── 2020_05_20_234655_add_mounts_table.php │ ├── 2020_05_21_192756_add_mount_server_table.php │ ├── 2020_07_02_213612_create_user_recovery_tokens_table.php │ ├── 2020_07_09_201845_add_notes_column_for_allocations.php │ ├── 2020_08_20_205533_add_backup_state_column_to_backups.php │ ├── 2020_08_22_132500_update_bytes_to_unsigned_bigint.php │ ├── 2020_08_23_175331_modify_checksums_column_for_backups.php │ ├── 2020_09_13_110007_drop_packs_from_servers.php │ ├── 2020_09_13_110021_drop_packs_from_api_key_permissions.php │ ├── 2020_09_13_110047_drop_packs_table.php │ ├── 2020_09_13_113503_drop_daemon_key_table.php │ ├── 2020_10_10_165437_change_unique_database_name_to_account_for_server.php │ ├── 2020_10_26_194904_remove_nullable_from_schedule_name_field.php │ ├── 2020_11_02_201014_add_features_column_to_eggs.php │ ├── 2020_12_12_102435_support_multiple_docker_images_and_updates.php │ ├── 2020_12_14_013707_make_successful_nullable_in_server_transfers.php │ ├── 2020_12_17_014330_add_archived_field_to_server_transfers_table.php │ ├── 2020_12_24_092449_make_allocation_fields_json.php │ ├── 2020_12_26_184914_add_upload_id_column_to_backups_table.php │ ├── 2021_01_10_153937_add_file_denylist_to_egg_configs.php │ ├── 2021_01_13_013420_add_cron_month.php │ ├── 2021_01_17_102401_create_audit_logs_table.php │ ├── 2021_01_17_152623_add_generic_server_status_column.php │ ├── 2021_01_26_210502_update_file_denylist_to_json.php │ ├── 2021_02_23_205021_add_index_for_server_and_action.php │ ├── 2021_02_23_212657_make_sftp_port_unsigned_int.php │ ├── 2021_03_21_104718_force_cron_month_field_to_have_value_if_missing.php │ ├── 2021_05_01_092457_add_continue_on_failure_option_to_tasks.php │ ├── 2021_05_01_092523_add_only_run_when_server_online_option_to_schedules.php │ ├── 2021_05_03_201016_add_support_for_locking_a_backup.php │ ├── 2021_07_12_013420_remove_userinteraction.php │ ├── 2021_07_17_211512_create_user_ssh_keys_table.php │ ├── 2021_08_03_210600_change_successful_field_to_default_to_false_on_backups_table.php │ ├── 2021_08_21_175111_add_foreign_keys_to_mount_node_table.php │ ├── 2021_08_21_175118_add_foreign_keys_to_mount_server_table.php │ ├── 2021_08_21_180921_add_foreign_keys_to_egg_mount_table.php │ ├── 2022_01_02_204701_create_credits_table.php │ ├── 2022_01_10_220605_add_credits_to_api_permissions.php │ ├── 2022_01_25_030847_drop_google_analytics.php │ ├── 2022_01_25_165202_add_credits_to_users.php │ ├── 2022_04_06_000312_create_notifs_table.php │ ├── 2022_05_07_165334_migrate_egg_images_array_to_new_format.php │ ├── 2022_05_28_135717_create_activity_logs_table.php │ └── 2022_05_29_140349_create_activity_log_actors_table.php ├── docker-compose.example.yml ├── package.json ├── phpunit.xml ├── public ├── .gitignore ├── .htaccess ├── assets │ └── svgs │ │ ├── not_found.svg │ │ ├── pterodactyl.svg │ │ ├── server_error.svg │ │ └── server_installing.svg ├── favicons │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── android-icon-144x144.png │ ├── android-icon-192x192.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 │ ├── apple-icon-57x57.png │ ├── apple-icon-60x60.png │ ├── apple-icon-72x72.png │ ├── apple-icon-76x76.png │ ├── apple-icon-precomposed.png │ ├── apple-icon.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── df4b367461890fa5fd0d9339d3c3f9c6.ico.zip │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── favicon.ico │ ├── manifest.json │ ├── ms-icon-144x144.png │ ├── ms-icon-150x150.png │ ├── ms-icon-310x310.png │ ├── ms-icon-70x70.png │ ├── mstile-150x150.png │ └── safari-pinned-tab.svg ├── index.php ├── js │ ├── autocomplete.js │ ├── keyboard.polyfill.js │ └── laroute.js ├── robots.txt └── themes │ └── pterodactyl │ ├── css │ ├── checkbox.css │ └── pterodactyl.css │ ├── js │ ├── admin │ │ ├── functions.js │ │ ├── new-server.js │ │ └── server │ │ │ └── transfer.js │ └── plugins │ │ └── minecraft │ │ └── eula.js │ └── vendor │ ├── ace │ ├── ace.js │ ├── ext-elastic_tabstops_lite.js │ ├── ext-error_marker.js │ ├── ext-linking.js │ ├── ext-modelist.js │ ├── ext-old_ie.js │ ├── ext-searchbox.js │ ├── ext-settings_menu.js │ ├── ext-spellcheck.js │ ├── ext-split.js │ ├── ext-static_highlight.js │ ├── ext-textarea.js │ ├── ext-themelist.js │ ├── ext-whitespace.js │ ├── keybinding-emacs.js │ ├── keybinding-vim.js │ ├── mode-assembly_x86.js │ ├── mode-c_cpp.js │ ├── mode-coffee.js │ ├── mode-csharp.js │ ├── mode-css.js │ ├── mode-golang.js │ ├── mode-haml.js │ ├── mode-html.js │ ├── mode-ini.js │ ├── mode-java.js │ ├── mode-javascript.js │ ├── mode-json.js │ ├── mode-kotlin.js │ ├── mode-lua.js │ ├── mode-markdown.js │ ├── mode-mysql.js │ ├── mode-objectivec.js │ ├── mode-perl.js │ ├── mode-php.js │ ├── mode-plain_text.js │ ├── mode-properties.js │ ├── mode-python.js │ ├── mode-ruby.js │ ├── mode-rust.js │ ├── mode-sh.js │ ├── mode-smarty.js │ ├── mode-sql.js │ ├── mode-xml.js │ ├── mode-yaml.js │ ├── theme-chrome.js │ ├── worker-css.js │ ├── worker-html.js │ ├── worker-javascript.js │ ├── worker-json.js │ ├── worker-lua.js │ ├── worker-php.js │ └── worker-xml.js │ ├── adminlte │ ├── admin.min.css │ ├── adminlte.min.css.map │ ├── app.min.js │ └── colors │ │ └── skin-blue.min.css │ ├── animate │ └── animate.min.css │ ├── ansi │ └── ansi_up.js │ ├── async │ ├── async.min.js │ └── async.min.map │ ├── bootstrap-notify │ └── bootstrap-notify.min.js │ ├── bootstrap │ ├── bootstrap-theme.min.css │ ├── bootstrap-theme.min.css.map │ ├── bootstrap.min.css │ ├── bootstrap.min.css.map │ └── bootstrap.min.js │ ├── chartjs │ └── chart.min.js │ ├── fontawesome │ └── animation.min.css │ ├── jquery │ ├── date-format.min.js │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map │ ├── lodash │ └── lodash.js │ ├── mousewheel │ └── jquery.mousewheel-min.js │ ├── particlesjs │ ├── particles.json │ └── particles.min.js │ ├── select2 │ ├── select2.full.min.js │ └── select2.min.css │ ├── siofu │ └── client.min.js │ ├── slimscroll │ └── jquery.slimscroll.min.js │ ├── socketio │ ├── socket.io.js.map │ └── socket.io.v203.min.js │ └── sweetalert │ ├── sweetalert.min.css │ └── sweetalert.min.js ├── resources ├── lang │ └── en │ │ ├── admin │ │ ├── nests.php │ │ ├── node.php │ │ ├── server.php │ │ └── user.php │ │ ├── auth.php │ │ ├── command │ │ └── messages.php │ │ ├── dashboard │ │ ├── account.php │ │ └── index.php │ │ ├── exceptions.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ ├── server │ │ └── users.php │ │ ├── strings.php │ │ └── validation.php ├── scripts │ ├── TransitionRouter.tsx │ ├── api │ │ ├── account │ │ │ ├── createApiKey.ts │ │ │ ├── deleteApiKey.ts │ │ │ ├── deleteNotifications.ts │ │ │ ├── disableAccountTwoFactor.ts │ │ │ ├── enableAccountTwoFactor.ts │ │ │ ├── getApiKeys.ts │ │ │ ├── getNotifications.ts │ │ │ ├── getTwoFactorTokenData.ts │ │ │ ├── ssh-keys.ts │ │ │ ├── updateAccountEmail.ts │ │ │ ├── updateAccountPassword.ts │ │ │ ├── updateAccountUsername.ts │ │ │ └── webauthn │ │ │ │ ├── deleteWebauthnKey.ts │ │ │ │ ├── getWebauthnKeys.ts │ │ │ │ ├── registerWebauthnKey.ts │ │ │ │ └── webauthnChallenge.ts │ │ ├── auth │ │ │ ├── login.ts │ │ │ ├── loginCheckpoint.ts │ │ │ ├── performPasswordReset.ts │ │ │ ├── register.ts │ │ │ └── requestPasswordResetEmail.ts │ │ ├── definitions │ │ │ ├── helpers.ts │ │ │ ├── index.d.ts │ │ │ └── user │ │ │ │ ├── index.ts │ │ │ │ ├── models.d.ts │ │ │ │ └── transformers.ts │ │ ├── getServers.ts │ │ ├── getSystemPermissions.ts │ │ ├── http.ts │ │ ├── interceptors.ts │ │ ├── server │ │ │ ├── backups │ │ │ │ ├── createServerBackup.ts │ │ │ │ ├── deleteBackup.ts │ │ │ │ ├── getBackupDownloadUrl.ts │ │ │ │ └── index.ts │ │ │ ├── databases │ │ │ │ ├── createServerDatabase.ts │ │ │ │ ├── deleteServerDatabase.ts │ │ │ │ ├── getServerDatabases.ts │ │ │ │ └── rotateDatabasePassword.ts │ │ │ ├── deleteServer.ts │ │ │ ├── files │ │ │ │ ├── chmodFiles.ts │ │ │ │ ├── compressFiles.ts │ │ │ │ ├── copyFile.ts │ │ │ │ ├── createDirectory.ts │ │ │ │ ├── decompressFiles.ts │ │ │ │ ├── deleteFiles.ts │ │ │ │ ├── getFileContents.ts │ │ │ │ ├── getFileDownloadUrl.ts │ │ │ │ ├── getFileUploadUrl.ts │ │ │ │ ├── loadDirectory.ts │ │ │ │ ├── renameFiles.ts │ │ │ │ └── saveFileContents.ts │ │ │ ├── getServer.ts │ │ │ ├── getServerResourceUsage.ts │ │ │ ├── getWebsocketToken.ts │ │ │ ├── network │ │ │ │ ├── createServerAllocation.ts │ │ │ │ ├── deleteServerAllocation.ts │ │ │ │ ├── setPrimaryServerAllocation.ts │ │ │ │ └── setServerAllocationNotes.ts │ │ │ ├── reinstallServer.ts │ │ │ ├── renameServer.ts │ │ │ ├── schedules │ │ │ │ ├── createOrUpdateSchedule.ts │ │ │ │ ├── createOrUpdateScheduleTask.ts │ │ │ │ ├── deleteSchedule.ts │ │ │ │ ├── deleteScheduleTask.ts │ │ │ │ ├── getServerSchedule.ts │ │ │ │ ├── getServerSchedules.ts │ │ │ │ └── triggerScheduleExecution.ts │ │ │ ├── setSelectedDockerImage.ts │ │ │ ├── types.d.ts │ │ │ ├── updateStartupVariable.ts │ │ │ └── users │ │ │ │ ├── createOrUpdateSubuser.ts │ │ │ │ ├── deleteSubuser.ts │ │ │ │ └── getServerSubusers.ts │ │ ├── store │ │ │ ├── buy │ │ │ │ ├── buyCPU.ts │ │ │ │ ├── buyCredits.ts │ │ │ │ ├── buyRAM.ts │ │ │ │ ├── buySlots.ts │ │ │ │ └── buyStorage.ts │ │ │ ├── createServer.ts │ │ │ └── getConfig.ts │ │ ├── swr │ │ │ ├── getServerAllocations.ts │ │ │ ├── getServerAuditLogs.ts │ │ │ ├── getServerBackups.ts │ │ │ └── getServerStartup.ts │ │ └── transformers.ts │ ├── assets │ │ ├── css │ │ │ ├── GlobalStylesheet.ts │ │ │ └── jexactyl.css │ │ └── images │ │ │ ├── not_found.svg │ │ │ ├── payment_error.svg │ │ │ ├── payment_success.svg │ │ │ ├── pterodactyl.svg │ │ │ ├── server_error.svg │ │ │ ├── server_installing.svg │ │ │ └── server_restore.svg │ ├── components │ │ ├── App.tsx │ │ ├── FlashMessageRender.tsx │ │ ├── MessageBox.tsx │ │ ├── auth │ │ │ ├── ForgotPasswordContainer.tsx │ │ │ ├── LoginCheckpointContainer.tsx │ │ │ ├── LoginContainer.tsx │ │ │ ├── LoginFormContainer.tsx │ │ │ ├── LoginKeyCheckpointContainer.tsx │ │ │ ├── RegisterContainer.tsx │ │ │ └── ResetPasswordContainer.tsx │ │ ├── dashboard │ │ │ ├── AccountApiContainer.tsx │ │ │ ├── AccountNotificationsContainer.tsx │ │ │ ├── AccountOverviewContainer.tsx │ │ │ ├── ApiKeyModal.tsx │ │ │ ├── DashboardContainer.tsx │ │ │ ├── SecurityKeyContainer.tsx │ │ │ ├── ServerRow.tsx │ │ │ ├── forms │ │ │ │ ├── ConfigureTwoFactorForm.tsx │ │ │ │ ├── CreateApiKeyForm.tsx │ │ │ │ ├── DisableTwoFactorModal.tsx │ │ │ │ ├── SetupTwoFactorModal.tsx │ │ │ │ ├── UpdateEmailAddressForm.tsx │ │ │ │ ├── UpdatePasswordForm.tsx │ │ │ │ └── UpdateUsernameForm.tsx │ │ │ ├── search │ │ │ │ ├── SearchContainer.tsx │ │ │ │ └── SearchModal.tsx │ │ │ └── ssh │ │ │ │ ├── AccountSSHContainer.tsx │ │ │ │ ├── CreateSSHKeyForm.tsx │ │ │ │ └── DeleteSSHKeyButton.tsx │ │ ├── elements │ │ │ ├── AuthenticatedRoute.tsx │ │ │ ├── Button.tsx │ │ │ ├── Can.tsx │ │ │ ├── Checkbox.tsx │ │ │ ├── CodemirrorEditor.tsx │ │ │ ├── ConfirmationModal.tsx │ │ │ ├── ContentBox.tsx │ │ │ ├── ContentContainer.tsx │ │ │ ├── CopyOnClick.tsx │ │ │ ├── DashboardSwitch.tsx │ │ │ ├── DropdownMenu.tsx │ │ │ ├── ErrorBoundary.tsx │ │ │ ├── Fade.tsx │ │ │ ├── Field.tsx │ │ │ ├── FormikFieldWrapper.tsx │ │ │ ├── FormikSwitch.tsx │ │ │ ├── GreyRowBox.tsx │ │ │ ├── Icon.tsx │ │ │ ├── Input.tsx │ │ │ ├── InputError.tsx │ │ │ ├── InputSpinner.tsx │ │ │ ├── Label.tsx │ │ │ ├── Modal.tsx │ │ │ ├── PageContentBlock.tsx │ │ │ ├── Pagination.tsx │ │ │ ├── ProgressBar.tsx │ │ │ ├── RainbowProgressBar.tsx │ │ │ ├── ScreenBlock.tsx │ │ │ ├── Select.tsx │ │ │ ├── ServerContentBlock.tsx │ │ │ ├── Sidebar.tsx │ │ │ ├── Spinner.tsx │ │ │ ├── SpinnerOverlay.tsx │ │ │ ├── StaticSubNavigation.tsx │ │ │ ├── SubNavigation.tsx │ │ │ ├── Switch.tsx │ │ │ └── TitledGreyBox.tsx │ │ ├── helpers.ts │ │ ├── history.ts │ │ ├── server │ │ │ ├── Console.tsx │ │ │ ├── InstallListener.tsx │ │ │ ├── PowerControls.tsx │ │ │ ├── ServerConsole.tsx │ │ │ ├── ServerDetailsBlock.tsx │ │ │ ├── StatBars.tsx │ │ │ ├── StatGraphs.tsx │ │ │ ├── StopOrKillButton.tsx │ │ │ ├── TransferListener.tsx │ │ │ ├── UptimeDuration.tsx │ │ │ ├── WebsocketHandler.tsx │ │ │ ├── auditlogs │ │ │ │ ├── AuditLogHandler.ts │ │ │ │ ├── AuditLogRow.tsx │ │ │ │ └── AuditLogsContainer.tsx │ │ │ ├── backups │ │ │ │ ├── BackupContainer.tsx │ │ │ │ ├── BackupContextMenu.tsx │ │ │ │ ├── BackupRow.tsx │ │ │ │ └── CreateBackupButton.tsx │ │ │ ├── databases │ │ │ │ ├── CreateDatabaseButton.tsx │ │ │ │ ├── DatabaseRow.tsx │ │ │ │ ├── DatabasesContainer.tsx │ │ │ │ └── RotatePasswordButton.tsx │ │ │ ├── events.ts │ │ │ ├── features │ │ │ │ ├── GSLTokenModalFeature.tsx │ │ │ │ ├── JavaVersionModalFeature.tsx │ │ │ │ ├── PIDLimitModalFeature.tsx │ │ │ │ ├── SteamDiskSpaceFeature.tsx │ │ │ │ ├── eula │ │ │ │ │ └── EulaModalFeature.tsx │ │ │ │ └── index.ts │ │ │ ├── files │ │ │ │ ├── ChmodFileModal.tsx │ │ │ │ ├── FileDropdownMenu.tsx │ │ │ │ ├── FileEditContainer.tsx │ │ │ │ ├── FileManagerBreadcrumbs.tsx │ │ │ │ ├── FileManagerContainer.tsx │ │ │ │ ├── FileNameModal.tsx │ │ │ │ ├── FileObjectRow.tsx │ │ │ │ ├── MassActionsBar.tsx │ │ │ │ ├── NewDirectoryButton.tsx │ │ │ │ ├── RenameFileModal.tsx │ │ │ │ ├── SelectFileCheckbox.tsx │ │ │ │ └── UploadButton.tsx │ │ │ ├── network │ │ │ │ ├── AllocationRow.tsx │ │ │ │ ├── DeleteAllocationButton.tsx │ │ │ │ └── NetworkContainer.tsx │ │ │ ├── schedules │ │ │ │ ├── DeleteScheduleButton.tsx │ │ │ │ ├── EditScheduleModal.tsx │ │ │ │ ├── NewTaskButton.tsx │ │ │ │ ├── RunScheduleButton.tsx │ │ │ │ ├── ScheduleCheatsheetCards.tsx │ │ │ │ ├── ScheduleCheetsheetCards.tsx │ │ │ │ ├── ScheduleContainer.tsx │ │ │ │ ├── ScheduleCronRow.tsx │ │ │ │ ├── ScheduleEditContainer.tsx │ │ │ │ ├── ScheduleRow.tsx │ │ │ │ ├── ScheduleTaskRow.tsx │ │ │ │ └── TaskDetailsModal.tsx │ │ │ ├── settings │ │ │ │ ├── DeleteServerBox.tsx │ │ │ │ ├── ReinstallServerBox.tsx │ │ │ │ ├── RenameServerBox.tsx │ │ │ │ └── SettingsContainer.tsx │ │ │ ├── startup │ │ │ │ ├── StartupContainer.tsx │ │ │ │ └── VariableBox.tsx │ │ │ └── users │ │ │ │ ├── AddSubuserButton.tsx │ │ │ │ ├── EditSubuserModal.tsx │ │ │ │ ├── PermissionRow.tsx │ │ │ │ ├── PermissionSelectAll.tsx │ │ │ │ ├── PermissionTitleBox.tsx │ │ │ │ ├── RemoveSubuserButton.tsx │ │ │ │ ├── UserRow.tsx │ │ │ │ └── UsersContainer.tsx │ │ ├── store │ │ │ ├── ActionsRow.tsx │ │ │ ├── ResourceRow.tsx │ │ │ ├── StoreContainer.tsx │ │ │ ├── UserInformationRow.tsx │ │ │ ├── payments │ │ │ │ ├── PaymentCancelContainer.tsx │ │ │ │ └── PaymentSuccessContainer.tsx │ │ │ └── servers │ │ │ │ └── CreateServerContainer.tsx │ │ └── types.ts │ ├── context │ │ └── ModalContext.ts │ ├── easy-peasy.d.ts │ ├── globals.d.ts │ ├── helpers.ts │ ├── hoc │ │ ├── RequireServerPermission.tsx │ │ └── asModal.tsx │ ├── i18n.ts │ ├── index.tsx │ ├── macros.d.ts │ ├── modes.ts │ ├── plugins │ │ ├── Websocket.ts │ │ ├── XtermScrollDownHelperAddon.ts │ │ ├── useDeepCompareEffect.ts │ │ ├── useDeepCompareMemo.ts │ │ ├── useDeepMemoize.ts │ │ ├── useEventListener.ts │ │ ├── useFileManagerSwr.ts │ │ ├── useFlash.ts │ │ ├── usePermissions.ts │ │ ├── usePersistedState.ts │ │ ├── useUserPersistedState.ts │ │ ├── useUserSWRContentKey.ts │ │ ├── useWebsocketEvent.ts │ │ └── useWindowDimensions.ts │ ├── routers │ │ ├── AuthenticationRouter.tsx │ │ ├── DashboardRouter.tsx │ │ ├── ServerRouter.tsx │ │ └── StoreRouter.tsx │ ├── state │ │ ├── flashes.ts │ │ ├── hooks.ts │ │ ├── index.ts │ │ ├── permissions.ts │ │ ├── progress.ts │ │ ├── server │ │ │ ├── databases.ts │ │ │ ├── files.ts │ │ │ ├── index.ts │ │ │ ├── schedules.ts │ │ │ ├── socket.ts │ │ │ └── subusers.ts │ │ ├── settings.ts │ │ └── user.ts │ └── theme.ts └── views │ ├── admin │ ├── api │ │ ├── index.blade.php │ │ └── new.blade.php │ ├── credits │ │ ├── index.blade.php │ │ ├── payments.blade.php │ │ └── store.blade.php │ ├── databases │ │ ├── index.blade.php │ │ └── view.blade.php │ ├── eggs │ │ ├── new.blade.php │ │ ├── scripts.blade.php │ │ ├── variables.blade.php │ │ └── view.blade.php │ ├── index.blade.php │ ├── locations │ │ ├── index.blade.php │ │ └── view.blade.php │ ├── logs │ │ └── index.blade.php │ ├── mounts │ │ ├── index.blade.php │ │ └── view.blade.php │ ├── nests │ │ ├── index.blade.php │ │ ├── new.blade.php │ │ └── view.blade.php │ ├── nodes │ │ ├── index.blade.php │ │ ├── new.blade.php │ │ └── view │ │ │ ├── allocation.blade.php │ │ │ ├── configuration.blade.php │ │ │ ├── index.blade.php │ │ │ ├── servers.blade.php │ │ │ └── settings.blade.php │ ├── servers │ │ ├── index.blade.php │ │ ├── new.blade.php │ │ ├── partials │ │ │ └── navigation.blade.php │ │ └── view │ │ │ ├── build.blade.php │ │ │ ├── database.blade.php │ │ │ ├── delete.blade.php │ │ │ ├── details.blade.php │ │ │ ├── index.blade.php │ │ │ ├── manage.blade.php │ │ │ ├── mounts.blade.php │ │ │ └── startup.blade.php │ ├── settings │ │ ├── advanced.blade.php │ │ ├── index.blade.php │ │ └── mail.blade.php │ ├── store │ │ └── index.blade.php │ └── users │ │ ├── index.blade.php │ │ ├── new.blade.php │ │ ├── resources.blade.php │ │ └── view.blade.php │ ├── layouts │ ├── admin.blade.php │ └── scripts.blade.php │ ├── partials │ ├── admin │ │ ├── credits │ │ │ └── nav.blade.php │ │ ├── settings │ │ │ ├── nav.blade.php │ │ │ └── notice.blade.php │ │ └── users │ │ │ └── nav.blade.php │ └── schedules │ │ └── task-template.blade.php │ ├── templates │ ├── auth │ │ └── core.blade.php │ ├── base │ │ └── core.blade.php │ └── wrapper.blade.php │ └── vendor │ ├── notifications │ ├── email-plain.blade.php │ └── email.blade.php │ └── pagination │ └── default.blade.php ├── routes ├── admin.php ├── api-application.php ├── api-client.php ├── api-remote.php ├── auth.php └── base.php ├── server.php ├── storage ├── app │ ├── .gitignore │ └── packs │ │ └── .githold ├── clockwork │ └── .gitignore ├── debugbar │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ ├── .gitignore │ │ └── data │ │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tailwind.config.js ├── tests ├── Assertions │ └── MiddlewareAttributeAssertionsTrait.php ├── CreatesApplication.php ├── Integration │ ├── Api │ │ ├── Application │ │ │ ├── ApplicationApiIntegrationTestCase.php │ │ │ ├── Location │ │ │ │ └── LocationControllerTest.php │ │ │ ├── Nests │ │ │ │ ├── EggControllerTest.php │ │ │ │ └── NestControllerTest.php │ │ │ └── Users │ │ │ │ ├── ExternalUserControllerTest.php │ │ │ │ └── UserControllerTest.php │ │ ├── Client │ │ │ ├── AccountControllerTest.php │ │ │ ├── ApiKeyControllerTest.php │ │ │ ├── ClientApiIntegrationTestCase.php │ │ │ ├── ClientControllerTest.php │ │ │ ├── SSHKeyControllerTest.php │ │ │ ├── Server │ │ │ │ ├── Allocation │ │ │ │ │ ├── AllocationAuthorizationTest.php │ │ │ │ │ ├── CreateNewAllocationTest.php │ │ │ │ │ └── DeleteAllocationTest.php │ │ │ │ ├── Backup │ │ │ │ │ ├── BackupAuthorizationTest.php │ │ │ │ │ └── DeleteBackupTest.php │ │ │ │ ├── CommandControllerTest.php │ │ │ │ ├── Database │ │ │ │ │ └── DatabaseAuthorizationTest.php │ │ │ │ ├── NetworkAllocationControllerTest.php │ │ │ │ ├── PowerControllerTest.php │ │ │ │ ├── ResourceUtilitizationControllerTest.php │ │ │ │ ├── Schedule │ │ │ │ │ ├── CreateServerScheduleTest.php │ │ │ │ │ ├── DeleteServerScheduleTest.php │ │ │ │ │ ├── ExecuteScheduleTest.php │ │ │ │ │ ├── GetServerSchedulesTest.php │ │ │ │ │ ├── ScheduleAuthorizationTest.php │ │ │ │ │ └── UpdateServerScheduleTest.php │ │ │ │ ├── ScheduleTask │ │ │ │ │ ├── CreateServerScheduleTaskTest.php │ │ │ │ │ └── DeleteScheduleTaskTest.php │ │ │ │ ├── SettingsControllerTest.php │ │ │ │ ├── Subuser │ │ │ │ │ ├── CreateServerSubuserTest.php │ │ │ │ │ ├── DeleteSubuserTest.php │ │ │ │ │ └── SubuserAuthorizationTest.php │ │ │ │ └── WebsocketControllerTest.php │ │ │ └── TwoFactorControllerTest.php │ │ └── Remote │ │ │ └── SftpAuthenticationControllerTest.php │ ├── Http │ │ └── Controllers │ │ │ └── Admin │ │ │ └── UserControllerTest.php │ ├── IntegrationTestCase.php │ ├── Jobs │ │ └── Schedule │ │ │ └── RunTaskJobTest.php │ ├── Services │ │ ├── Allocations │ │ │ └── FindAssignableAllocationServiceTest.php │ │ ├── Backups │ │ │ └── DeleteBackupServiceTest.php │ │ ├── Databases │ │ │ ├── DatabaseManagementServiceTest.php │ │ │ └── DeployServerDatabaseServiceTest.php │ │ ├── Deployment │ │ │ └── FindViableNodesServiceTest.php │ │ ├── Schedules │ │ │ └── ProcessScheduleServiceTest.php │ │ └── Servers │ │ │ ├── ServerCreationServiceTest.php │ │ │ ├── StartupModificationServiceTest.php │ │ │ └── VariableValidatorServiceTest.php │ └── TestResponse.php ├── TestCase.php ├── Traits │ ├── Http │ │ ├── IntegrationJsonRequestAssertions.php │ │ ├── MocksMiddlewareClosure.php │ │ └── RequestMockHelpers.php │ ├── Integration │ │ └── CreatesTestModels.php │ ├── MocksPdoConnection.php │ ├── MocksRequestException.php │ └── MocksUuids.php └── Unit │ ├── Helpers │ ├── EnvironmentWriterTraitTest.php │ └── IsDigitTest.php │ ├── Http │ └── Middleware │ │ ├── AdminAuthenticateTest.php │ │ ├── Api │ │ ├── Application │ │ │ └── AuthenticateUserTest.php │ │ └── Daemon │ │ │ └── DaemonAuthenticateTest.php │ │ ├── LanguageMiddlewareTest.php │ │ ├── MaintenanceMiddlewareTest.php │ │ ├── MiddlewareTestCase.php │ │ └── RedirectIfAuthenticatedTest.php │ ├── Rules │ └── UsernameTest.php │ └── Services │ └── Acl │ └── Api │ └── AdminAclTest.php ├── tsconfig.json ├── webpack.config.js └── yarn.lock /.babel-plugin-macrosrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | twin: { 3 | preset: 'styled-components', 4 | autoCssProp: true, 5 | }, 6 | styledComponents: { 7 | pure: true, 8 | displayName: true, 9 | fileName: true, 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 4 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | 11 | [.*yml] 12 | indent_size = 2 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.env.ci: -------------------------------------------------------------------------------- 1 | APP_ENV=testing 2 | APP_DEBUG=true 3 | APP_KEY=SomeRandomString3232RandomString 4 | APP_THEME=pterodactyl 5 | APP_TIMEZONE=America/Los_Angeles 6 | APP_URL=http://localhost/ 7 | 8 | DB_HOST=127.0.0.1 9 | DB_DATABASE=panel_test 10 | DB_USERNAME=root 11 | DB_PASSWORD= 12 | 13 | CACHE_DRIVER=array 14 | SESSION_DRIVER=array 15 | MAIL_DRIVER=array 16 | QUEUE_DRIVER=sync 17 | 18 | HASHIDS_SALT=test123 19 | APP_ENVIRONMENT_ONLY=true 20 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | public 2 | node_modules 3 | resources/views 4 | webpack.config.js 5 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build Panel 2 | on: 3 | push: 4 | branches: 5 | - 'develop' 6 | - 'v2' 7 | pull_request: 8 | jobs: 9 | build: 10 | runs-on: ubuntu-20.04 11 | if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, 'ci skip')" 12 | strategy: 13 | matrix: 14 | node-version: [16.x] 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v2 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | cache: 'npm' 22 | - run: npm install -g yarn 23 | - run: yarn install 24 | - run: yarn build:production 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | *.DS_Store* 3 | !.env.ci 4 | !.env.example 5 | .env* 6 | .vagrant/* 7 | .vscode/* 8 | storage/framework/* 9 | /.idea 10 | /nbproject 11 | 12 | node_modules 13 | *.log 14 | _ide_helper.php 15 | _ide_helper_models.php 16 | .phpstorm.meta.php 17 | .yarn 18 | public/assets/manifest.json 19 | 20 | # For local development with docker 21 | # Remove if we ever put the Dockerfile in the repo 22 | .dockerignore 23 | docker-compose.yml 24 | 25 | # for image related files 26 | misc 27 | .php-cs-fixer.cache 28 | coverage.xml 29 | resources/lang/locales.js 30 | .phpunit.result.cache 31 | -------------------------------------------------------------------------------- /.yarnclean: -------------------------------------------------------------------------------- 1 | @types/react-native 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jexactyl Panel - v2.x 2 | 3 | This repository holds the code for Jexactyl v2, and has been archived due to this version being replaced with [v3](https://github.com/jexactyl/jexactyl). 4 | 5 | ### Reporting a vulnerability 6 | Please report any issues directly to `contact@heyim.cam`. 7 | -------------------------------------------------------------------------------- /app/Console/Commands/Overrides/SeedCommand.php: -------------------------------------------------------------------------------- 1 | hasCompletedMigrations()) { 19 | $this->showMigrationWarning(); 20 | 21 | return; 22 | } 23 | 24 | parent::handle(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Console/Commands/Overrides/UpCommand.php: -------------------------------------------------------------------------------- 1 | hasCompletedMigrations()) { 19 | $this->showMigrationWarning(); 20 | 21 | return; 22 | } 23 | 24 | parent::handle(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Contracts/Core/ReceivesEvents.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/Contracts/Http/ClientPermissionsRequest.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/Contracts/Repository/DatabaseHostRepositoryInterface.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Contracts/Repository/ScheduleRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | user = $user; 16 | $this->recovery = $recovery; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Events/Event.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/Installed.php: -------------------------------------------------------------------------------- 1 | server = $server; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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/Http/HttpForbiddenException.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/Http/TwoFactorAuthRequiredException.php: -------------------------------------------------------------------------------- 1 | $port])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Exceptions/Service/Allocation/NoAutoAllocationSpaceAvailableException.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/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/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/Exceptions/Service/Egg/Variable/BadValidationRuleException.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/HasActiveServersException.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/Exceptions/Service/InvalidFileUploadException.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/Exceptions/Service/Location/HasActiveNodesException.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/ServiceLimitExceededException.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/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 | -------------------------------------------------------------------------------- /app/Exceptions/Service/User/TwoFactorAuthenticationTokenInvalid.php: -------------------------------------------------------------------------------- 1 | accessToken = $accessToken; 21 | $this->plainTextToken = $plainTextToken; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Extensions/Themes/Theme.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/Facades/LogBatch.php: -------------------------------------------------------------------------------- 1 | orderBy('id', 'DESC')->get(); 13 | $logs = json_decode(json_encode($logs), true); 14 | return view('admin.logs.index', [ 15 | 'logs' => $logs, 16 | ]); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | user()); 18 | LogTarget::setSubject($request->user()); 19 | 20 | return $next($request); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.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/Admin/BillingFormRequest.php: -------------------------------------------------------------------------------- 1 | 'int', 16 | ]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/Credits/ConfigFormRequest.php: -------------------------------------------------------------------------------- 1 | 'int', 16 | ]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/Credits/PaymentsFormRequest.php: -------------------------------------------------------------------------------- 1 | 'int', 16 | 'paypal_id' => 'string', 17 | 'paypal_secret' => 'string', 18 | 'currency' => 'string' 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/Credits/StoreFormRequest.php: -------------------------------------------------------------------------------- 1 | 'int|nullable', 16 | 'slots_cost' => 'int|nullable', 17 | 'cpu_cost' => 'int|nullable', 18 | 'ram_cost' => 'int|nullable', 19 | 'storage_cost' => 'int|nullable', 20 | 'credits_cost' => 'string|nullable' 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /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/Admin/Nest/StoreNestFormRequest.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/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/Admin/Users/UserResourceFormRequest.php: -------------------------------------------------------------------------------- 1 | route()->parameter('user')))->only([ 14 | 'cr_balance', 15 | 'cr_cpu', 16 | 'cr_ram', 17 | 'cr_storage', 18 | 'cr_slots' 19 | ])->toArray(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Allocations/DeleteAllocationRequest.php: -------------------------------------------------------------------------------- 1 | route()->parameter('location')->id; 15 | 16 | return collect(Location::getRulesForUpdate($locationId))->only([ 17 | 'short', 18 | 'long', 19 | ])->toArray(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Nests/Eggs/GetEggRequest.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/Http/Requests/Api/Application/Nodes/GetNodeRequest.php: -------------------------------------------------------------------------------- 1 | route()->parameter('node')->id; 16 | 17 | return parent::rules(Node::getRulesForUpdate($node)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Servers/Databases/GetServerDatabaseRequest.php: -------------------------------------------------------------------------------- 1 | 'string|max:100', 11 | ]; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Application/Servers/ServerWriteRequest.php: -------------------------------------------------------------------------------- 1 | parameter('user', User::class)->id; 15 | 16 | return parent::rules(User::getRulesForUpdate($userId)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/GetServersRequest.php: -------------------------------------------------------------------------------- 1 | 'nullable|string|max:191', 22 | 'is_locked' => 'nullable|boolean', 23 | 'ignored' => 'nullable|string', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Databases/DeleteDatabaseRequest.php: -------------------------------------------------------------------------------- 1 | 'sometimes|nullable|string', 22 | 'files' => 'required|array', 23 | 'files.*' => 'string', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/CopyFileRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string', 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/CreateFolderRequest.php: -------------------------------------------------------------------------------- 1 | 'sometimes|nullable|string', 22 | 'name' => 'required|string', 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /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/Http/Requests/Api/Client/Servers/Files/DownloadFileRequest.php: -------------------------------------------------------------------------------- 1 | user()->can('file.read', $this->parameter('server', Server::class)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/ListFilesRequest.php: -------------------------------------------------------------------------------- 1 | 'sometimes|nullable|string', 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Files/UploadFileRequest.php: -------------------------------------------------------------------------------- 1 | array_merge($rules['notes'], ['present']), 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Schedules/DeleteScheduleRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|min:1', 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Settings/ReinstallServerRequest.php: -------------------------------------------------------------------------------- 1 | 'required|email|between:1,191', 21 | 'permissions' => 'required|array', 22 | 'permissions.*' => 'string', 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/Servers/Subusers/UpdateSubuserRequest.php: -------------------------------------------------------------------------------- 1 | 'required|array', 21 | 'permissions.*' => 'string', 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Client/StoreRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/Remote/InstallationDataRequest.php: -------------------------------------------------------------------------------- 1 | 'present|boolean', 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Http/Requests/Auth/LoginRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|min:1', 18 | 'password' => 'required|string', 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Requests/Auth/RegisterRequest.php: -------------------------------------------------------------------------------- 1 | only([ 27 | 'email', 'username', 'name_first', 'name_last', 28 | ])->toArray(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /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/Jobs/Job.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/Listeners/Auth/TwoFactorListener.php: -------------------------------------------------------------------------------- 1 | recovery ? 'auth:recovery-token' : 'auth:token') 13 | ->withRequestMetadata() 14 | ->subject($event->user) 15 | ->log(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Models/Billing.php: -------------------------------------------------------------------------------- 1 | 'required|string|between:1,191', 29 | 'value' => 'string', 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /app/Models/Credits.php: -------------------------------------------------------------------------------- 1 | 'required|string|between:1,191', 29 | 'value' => 'string', 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /app/Models/EggMount.php: -------------------------------------------------------------------------------- 1 | 'string', 23 | 'user_id' => 'integer', 24 | ]; 25 | } 26 | -------------------------------------------------------------------------------- /app/Models/Setting.php: -------------------------------------------------------------------------------- 1 | 'required|string|between:1,191', 29 | 'value' => 'string', 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /app/Models/WebauthnKey.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Observers/EggVariableObserver.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/Policies/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/app/Policies/.gitkeep -------------------------------------------------------------------------------- /app/Providers/ActivityLogServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->scoped(AcitvityLogBatchService::class); 18 | $this->app->scoped(ActivityLogTargetableService::class); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | id === (int) $userId; 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Providers/ViewComposerServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->make('view')->composer('*', AssetComposer::class); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Repositories/Eloquent/PermissionRepository.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | -------------------------------------------------------------------------------- /app/Traits/Controllers/PlainJavascriptInjection.php: -------------------------------------------------------------------------------- 1 | toArray(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Transformers/Api/Client/EggTransformer.php: -------------------------------------------------------------------------------- 1 | $egg->uuid, 24 | 'name' => $egg->name, 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@babel/typescript', 4 | ['@babel/env', { 5 | modules: false, 6 | useBuiltIns: 'entry', 7 | corejs: 3, 8 | }], 9 | '@babel/react', 10 | ], 11 | plugins: [ 12 | 'babel-plugin-macros', 13 | 'styled-components', 14 | 'react-hot-loader/babel', 15 | '@babel/transform-runtime', 16 | '@babel/transform-react-jsx', 17 | '@babel/proposal-class-properties', 18 | '@babel/proposal-object-rest-spread', 19 | '@babel/proposal-optional-chaining', 20 | '@babel/proposal-nullish-coalescing-operator', 21 | '@babel/syntax-dynamic-import', 22 | ], 23 | }; 24 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /config/activity.php: -------------------------------------------------------------------------------- 1 | env('APP_ACTIVITY_PRUNE_DAYS', 90), 9 | ]; 10 | -------------------------------------------------------------------------------- /config/egg_features/eula.php: -------------------------------------------------------------------------------- 1 | env('HASHIDS_SALT'), 13 | 'length' => env('HASHIDS_LENGTH', 8), 14 | 'alphabet' => env('HASHIDS_ALPHABET', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'), 15 | ]; 16 | -------------------------------------------------------------------------------- /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/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /database/Factories/LocationFactory.php: -------------------------------------------------------------------------------- 1 | Str::random(8), 25 | 'long' => Str::random(32), 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /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/Factories/ScheduleFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->firstName(), 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /database/Factories/SubuserFactory.php: -------------------------------------------------------------------------------- 1 | [ 25 | Permission::ACTION_WEBSOCKET_CONNECT, 26 | ], 27 | ]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /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/Seeders/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/database/Seeders/.gitkeep -------------------------------------------------------------------------------- /database/Seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(NestSeeder::class); 15 | $this->call(EggSeeder::class); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /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_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_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_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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /database/migrations/2016_01_25_234418_rename_permissions_column.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 | -------------------------------------------------------------------------------- /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_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_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_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_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 | -------------------------------------------------------------------------------- /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_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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/2017_09_10_225749_RenameTasksTableForStructureRefactor.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 | -------------------------------------------------------------------------------- /public/.gitignore: -------------------------------------------------------------------------------- 1 | assets/* 2 | !assets/svgs 3 | !assets/svgs/*.svg 4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /public/favicons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/favicons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/favicons/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/android-icon-144x144.png -------------------------------------------------------------------------------- /public/favicons/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/android-icon-192x192.png -------------------------------------------------------------------------------- /public/favicons/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/android-icon-36x36.png -------------------------------------------------------------------------------- /public/favicons/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/android-icon-48x48.png -------------------------------------------------------------------------------- /public/favicons/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/android-icon-72x72.png -------------------------------------------------------------------------------- /public/favicons/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/android-icon-96x96.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-114x114.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-120x120.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-144x144.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-152x152.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-180x180.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-57x57.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-60x60.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-72x72.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-76x76.png -------------------------------------------------------------------------------- /public/favicons/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon-precomposed.png -------------------------------------------------------------------------------- /public/favicons/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-icon.png -------------------------------------------------------------------------------- /public/favicons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/apple-touch-icon.png -------------------------------------------------------------------------------- /public/favicons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /public/favicons/df4b367461890fa5fd0d9339d3c3f9c6.ico.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/df4b367461890fa5fd0d9339d3c3f9c6.ico.zip -------------------------------------------------------------------------------- /public/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/favicon-96x96.png -------------------------------------------------------------------------------- /public/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/favicon.ico -------------------------------------------------------------------------------- /public/favicons/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/ms-icon-144x144.png -------------------------------------------------------------------------------- /public/favicons/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/ms-icon-150x150.png -------------------------------------------------------------------------------- /public/favicons/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/ms-icon-310x310.png -------------------------------------------------------------------------------- /public/favicons/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/ms-icon-70x70.png -------------------------------------------------------------------------------- /public/favicons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/public/favicons/mstile-150x150.png -------------------------------------------------------------------------------- /public/js/autocomplete.js: -------------------------------------------------------------------------------- 1 | // Hacky fix for browsers ignoring autocomplete="off" 2 | $(document).ready(function() { 3 | $('.form-autocomplete-stop').on('click', function () { 4 | $(this).removeAttr('readonly').blur().focus(); 5 | }); 6 | }); 7 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /public/themes/pterodactyl/vendor/ace/ext-error_marker.js: -------------------------------------------------------------------------------- 1 | ; 2 | (function() { 3 | window.require(["ace/ext/error_marker"], function() {}); 4 | })(); 5 | -------------------------------------------------------------------------------- /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}) -------------------------------------------------------------------------------- /resources/lang/en/admin/user.php: -------------------------------------------------------------------------------- 1 | . 5 | * 6 | * This software is licensed under the terms of the MIT license. 7 | * https://opensource.org/licenses/MIT 8 | */ 9 | 10 | return [ 11 | 'exceptions' => [ 12 | 'user_has_servers' => 'Cannot delete a user with active servers attached to their account. Please delete their servers before continuing.', 13 | ], 14 | 'notices' => [ 15 | 'account_created' => 'Account has been created successfully.', 16 | 'account_updated' => 'Account has been successfully updated.', 17 | ], 18 | ]; 19 | -------------------------------------------------------------------------------- /resources/lang/en/dashboard/index.php: -------------------------------------------------------------------------------- 1 | 'Search for servers...', 5 | 'no_matches' => 'There were no servers found matching the search criteria provided.', 6 | 'cpu_title' => 'CPU', 7 | 'memory_title' => 'Memory', 8 | ]; 9 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 16 | 'next' => 'Next »', 17 | ]; 18 | -------------------------------------------------------------------------------- /resources/scripts/api/account/createApiKey.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | import { ApiKey, rawDataToApiKey } from '@/api/account/getApiKeys'; 3 | 4 | export default (description: string, allowedIps: string): Promise => { 5 | return new Promise((resolve, reject) => { 6 | http.post('/api/client/account/api-keys', { 7 | description, 8 | allowed_ips: allowedIps.length > 0 ? allowedIps.split('\n') : [], 9 | }) 10 | .then(({ data }) => resolve({ 11 | ...rawDataToApiKey(data.attributes), 12 | // eslint-disable-next-line camelcase 13 | secretToken: data.meta?.secret_token ?? '', 14 | })) 15 | .catch(reject); 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/scripts/api/account/deleteNotifications.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.delete('/api/client/account/notifications') 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/account/disableAccountTwoFactor.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (password: string): Promise => { 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/enableAccountTwoFactor.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default async (code: string): Promise => { 4 | const { data } = await http.post('/api/client/account/two-factor', { code }); 5 | 6 | return data.attributes.tokens; 7 | }; 8 | -------------------------------------------------------------------------------- /resources/scripts/api/account/getTwoFactorTokenData.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export interface TwoFactorTokenData { 4 | // eslint-disable-next-line camelcase 5 | image_url_data: string; 6 | secret: string; 7 | } 8 | 9 | export default (): Promise => { 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/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/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 | -------------------------------------------------------------------------------- /resources/scripts/api/account/updateAccountUsername.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (username: string, password: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.put('/api/client/account/username', { username, password }) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/account/webauthn/deleteWebauthnKey.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (id: number): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.delete(`/api/client/account/webauthn/${id}`) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/auth/loginCheckpoint.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | import { LoginResponse } from '@/api/auth/login'; 3 | 4 | export default (token: string, code: string, recoveryToken?: string): Promise => { 5 | return new Promise((resolve, reject) => { 6 | http.post('/auth/login/checkpoint', { 7 | confirmation_token: token, 8 | authentication_code: code, 9 | recovery_token: (recoveryToken && recoveryToken.length > 0) ? recoveryToken : undefined, 10 | }) 11 | .then(response => resolve({ 12 | complete: response.data.complete, 13 | intended: response.data.intended || undefined, 14 | })) 15 | .catch(reject); 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /resources/scripts/api/auth/requestPasswordResetEmail.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (email: string, recaptchaData?: string): Promise => { 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/api/definitions/user/index.ts: -------------------------------------------------------------------------------- 1 | export * from './models.d'; 2 | export { default as Transformers, MetaTransformers } from './transformers'; 3 | -------------------------------------------------------------------------------- /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/interceptors.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | import { AxiosError } from 'axios'; 3 | import { History } from 'history'; 4 | 5 | export const setupInterceptors = (history: History) => { 6 | http.interceptors.response.use(resp => resp, (error: AxiosError) => { 7 | if (error.response?.status === 400) { 8 | if (error.response?.data.errors?.[0].code === 'TwoFactorAuthRequiredException') { 9 | if (!window.location.pathname.startsWith('/account')) { 10 | history.replace('/account', { twoFactorRedirect: true }); 11 | } 12 | } 13 | } 14 | throw error; 15 | }); 16 | }; 17 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /resources/scripts/api/server/databases/createServerDatabase.ts: -------------------------------------------------------------------------------- 1 | import { rawDataToServerDatabase, ServerDatabase } from '@/api/server/databases/getServerDatabases'; 2 | import http from '@/api/http'; 3 | 4 | export default (uuid: string, data: { connectionsFrom: string; databaseName: string }): Promise => { 5 | return new Promise((resolve, reject) => { 6 | http.post(`/api/client/servers/${uuid}/databases`, { 7 | database: data.databaseName, 8 | remote: data.connectionsFrom, 9 | }, { 10 | params: { include: 'password' }, 11 | }) 12 | .then(response => resolve(rawDataToServerDatabase(response.data.attributes))) 13 | .catch(reject); 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /resources/scripts/api/server/databases/deleteServerDatabase.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, database: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.delete(`/api/client/servers/${uuid}/databases/${database}`) 6 | .then(() => resolve()) 7 | .catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/server/databases/rotateDatabasePassword.ts: -------------------------------------------------------------------------------- 1 | import { rawDataToServerDatabase, ServerDatabase } from '@/api/server/databases/getServerDatabases'; 2 | import http from '@/api/http'; 3 | 4 | export default (uuid: string, database: string): Promise => { 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/api/server/deleteServer.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/delete`, 6 | { uuid } 7 | ) 8 | .then(() => resolve()) 9 | .catch(reject); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /resources/scripts/api/server/files/chmodFiles.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | interface Data { 4 | file: string; 5 | mode: string; 6 | } 7 | 8 | export default (uuid: string, directory: string, files: Data[]): Promise => { 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/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(`/api/client/servers/${uuid}/files/compress`, { root: directory, files }, { 7 | timeout: 60000, 8 | timeoutErrorMessage: 'It looks like this archive is taking a long time to generate. It will appear once completed.', 9 | }); 10 | 11 | return rawDataToFileObject(data); 12 | }; 13 | -------------------------------------------------------------------------------- /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/createDirectory.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, root: string, name: string): Promise => { 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 | -------------------------------------------------------------------------------- /resources/scripts/api/server/files/decompressFiles.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default async (uuid: string, directory: string, file: string): Promise => { 4 | await http.post(`/api/client/servers/${uuid}/files/decompress`, { root: directory, file }, { 5 | timeout: 300000, 6 | timeoutErrorMessage: 'It looks like this archive is taking a long time to be unarchived. Once completed the unarchived files will appear.', 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /resources/scripts/api/server/files/deleteFiles.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (uuid: string, directory: string, files: string[]): Promise => { 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/files/getFileContents.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (server: string, file: string): Promise => { 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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/scripts/api/server/files/saveFileContents.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default async (uuid: string, file: string, content: string): Promise => { 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 | -------------------------------------------------------------------------------- /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 }) => resolve({ 12 | token: data.data.token, 13 | socket: data.data.socket, 14 | })) 15 | .catch(reject); 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/scripts/api/server/network/deleteServerAllocation.ts: -------------------------------------------------------------------------------- 1 | import { Allocation } from '@/api/server/getServer'; 2 | import http from '@/api/http'; 3 | 4 | export default async (uuid: string, id: number): Promise => await http.delete(`/api/client/servers/${uuid}/network/allocations/${id}`); 5 | -------------------------------------------------------------------------------- /resources/scripts/api/server/network/setPrimaryServerAllocation.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): Promise => { 6 | const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}/primary`); 7 | 8 | return rawDataToServerAllocation(data); 9 | }; 10 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/scripts/api/server/schedules/triggerScheduleExecution.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default async (server: string, schedule: number): Promise => 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 | -------------------------------------------------------------------------------- /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/api/server/users/createOrUpdateSubuser.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | import { rawDataToServerSubuser } from '@/api/server/users/getServerSubusers'; 3 | import { Subuser } from '@/state/server/subusers'; 4 | 5 | interface Params { 6 | email: string; 7 | permissions: string[]; 8 | } 9 | 10 | export default (uuid: string, params: Params, subuser?: Subuser): Promise => { 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/scripts/api/store/buy/buyCPU.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.post('/api/client/store/buy/cpu') 6 | .then((data) => { 7 | resolve(data.data || []); 8 | }).catch(reject); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /resources/scripts/api/store/buy/buyCredits.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (value: string): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.post('/api/client/store/checkout', { value }).then((data) => { 6 | resolve(data.data || []); 7 | }).catch(reject); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/api/store/buy/buyRAM.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.post('/api/client/store/buy/ram') 6 | .then((data) => { 7 | resolve(data.data || []); 8 | }).catch(reject); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /resources/scripts/api/store/buy/buySlots.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.post('/api/client/store/buy/slots') 6 | .then((data) => { 7 | resolve(data.data || []); 8 | }).catch(reject); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /resources/scripts/api/store/buy/buyStorage.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.post('/api/client/store/buy/storage') 6 | .then((data) => { 7 | resolve(data.data || []); 8 | }).catch(reject); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /resources/scripts/api/store/createServer.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | 3 | export default (name: string, cpu: number, ram: number, storage: number): Promise => { 4 | return new Promise((resolve, reject) => { 5 | http.post('/api/client/store/create', { 6 | name, cpu, ram, storage, 7 | }).then((data) => { 8 | resolve(data.data || []); 9 | }).catch(reject); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /resources/scripts/api/store/getConfig.ts: -------------------------------------------------------------------------------- 1 | import http from '@/api/http'; 2 | import { ConfigResponse } from '@/components/store/servers/CreateServerContainer'; 3 | 4 | export default async (): Promise => { 5 | const { data } = await http.get('/api/client/store/config'); 6 | return (data.data || []); 7 | }; 8 | -------------------------------------------------------------------------------- /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([ 'server:allocations', uuid ], async () => { 11 | const { data } = await http.get(`/api/client/servers/${uuid}/network/allocations`); 12 | 13 | return (data.data || []).map(rawDataToServerAllocation); 14 | }, { revalidateOnFocus: false, revalidateOnMount: false }); 15 | }; 16 | -------------------------------------------------------------------------------- /resources/scripts/assets/css/jexactyl.css: -------------------------------------------------------------------------------- 1 | .serverRow { 2 | position: relative; 3 | width: 100%; 4 | min-height: 1px; 5 | padding-left: 15px; 6 | padding-right: 15px; 7 | } 8 | 9 | .row { 10 | display: flex; 11 | flex-wrap: wrap; 12 | margin-right: -15px; 13 | margin-left: -15px; 14 | } 15 | 16 | @media (min-width: 1200px) { 17 | .serverRow { 18 | flex: 0 0 50%; 19 | max-width: 50%; 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /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/ContentContainer.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | import { breakpoint } from '@/theme'; 3 | import tw from 'twin.macro'; 4 | 5 | const ContentContainer = styled.div` 6 | ${tw`mx-4`}; 7 | 8 | ${breakpoint('xl')` 9 | ${tw`pr-4`}; 10 | `}; 11 | `; 12 | ContentContainer.displayName = 'ContentContainer'; 13 | 14 | export default ContentContainer; 15 | -------------------------------------------------------------------------------- /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-900 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 bg-neutral-900 p-3`}; 11 | } 12 | `; 13 | -------------------------------------------------------------------------------- /resources/scripts/components/elements/Label.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | import tw from 'twin.macro'; 3 | 4 | const Label = styled.label<{ isLight?: boolean }>` 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 | -------------------------------------------------------------------------------- /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/elements/StaticSubNavigation.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/macro'; 2 | import tw from 'twin.macro'; 3 | 4 | const StaticSubNavigation = styled.div` 5 | ${tw`w-full overflow-x-auto`}; 6 | 7 | & > div { 8 | ${tw`flex items-center text-sm mx-auto px-2`}; 9 | max-width: 1200px; 10 | 11 | & > a, & > div { 12 | ${tw`inline-block py-4 px-4 text-neutral-300 no-underline whitespace-nowrap transition-all duration-150`}; 13 | 14 | &:not(:first-of-type) { 15 | ${tw`ml-2`}; 16 | } 17 | } 18 | } 19 | `; 20 | 21 | export default StaticSubNavigation; 22 | -------------------------------------------------------------------------------- /resources/scripts/components/helpers.ts: -------------------------------------------------------------------------------- 1 | import { StyledComponent } from 'styled-components/macro'; 2 | 3 | export const withSubComponents = , P extends Record> (component: C, properties: P): C & P => { 4 | Object.keys(properties).forEach((key: keyof P) => { 5 | (component as any)[key] = properties[key]; 6 | }); 7 | 8 | return component as C & P; 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/components/history.ts: -------------------------------------------------------------------------------- 1 | import { createBrowserHistory } from 'history'; 2 | 3 | export const history = createBrowserHistory({ basename: '/' }); 4 | -------------------------------------------------------------------------------- /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 <>{days}d {hours}h {minutes}m>; 12 | } 13 | 14 | return <>{hours}h {minutes}m {seconds}s>; 15 | }; 16 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/scripts/components/types.ts: -------------------------------------------------------------------------------- 1 | export interface WithClassname { 2 | className?: string; 3 | } 4 | -------------------------------------------------------------------------------- /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: (value: ((current: Readonly>) => Partial) | Partial | null) => void; 7 | } 8 | 9 | const ModalContext = React.createContext({ 10 | dismiss: () => null, 11 | setPropOverrides: () => null, 12 | }); 13 | 14 | ModalContext.displayName = 'ModalContext'; 15 | 16 | export default ModalContext; 17 | -------------------------------------------------------------------------------- /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( 8 | mapState: (state: State) => Result, 9 | ): Result; 10 | 11 | export function useStoreActions( 12 | mapActions: (actions: Actions) => Result, 13 | ): Result; 14 | } 15 | -------------------------------------------------------------------------------- /resources/scripts/globals.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.jpg'; 2 | declare module '*.png'; 3 | declare module '*.svg'; 4 | -------------------------------------------------------------------------------- /resources/scripts/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from '@/components/App'; 4 | import './i18n'; 5 | import { setConfig } from 'react-hot-loader'; 6 | 7 | import 'tailwindcss/dist/base.min.css'; 8 | import './assets/css/jexactyl.css'; 9 | 10 | // Prevents page reloads while making component changes which 11 | // also avoids triggering constant loading indicators all over 12 | // the place in development. 13 | // 14 | // @see https://github.com/gaearon/react-hot-loader#hook-support 15 | setConfig({ reloadHooks: false }); 16 | 17 | ReactDOM.render(, document.getElementById('app')); 18 | -------------------------------------------------------------------------------- /resources/scripts/plugins/useDeepCompareEffect.ts: -------------------------------------------------------------------------------- 1 | import { DependencyList, EffectCallback, useEffect } from 'react'; 2 | import { useDeepMemoize } from './useDeepMemoize'; 3 | 4 | export const useDeepCompareEffect = (callback: EffectCallback, dependencies: DependencyList) => 5 | useEffect(callback, useDeepMemoize(dependencies)); 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/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 | -------------------------------------------------------------------------------- /resources/scripts/plugins/useUserPersistedState.ts: -------------------------------------------------------------------------------- 1 | import { useStoreState } from 'easy-peasy'; 2 | import { usePersistedState } from '@/plugins/usePersistedState'; 3 | import { Dispatch, SetStateAction } from 'react'; 4 | 5 | export default (key: string, defaultValue: S): [ S, Dispatch> ] => { 6 | const uuid = useStoreState(state => state.user.data!.uuid); 7 | 8 | return usePersistedState(`${uuid}:${key}`, defaultValue); 9 | }; 10 | -------------------------------------------------------------------------------- /resources/scripts/plugins/useUserSWRContentKey.ts: -------------------------------------------------------------------------------- 1 | import { useStoreState } from '@/state/hooks'; 2 | 3 | export default (context: string | string[]) => { 4 | const key = Array.isArray(context) ? context.join(':') : context; 5 | const uuid = useStoreState(state => state.user.data?.uuid); 6 | 7 | if (!key.trim().length) { 8 | throw new Error('Must provide a valid context key to "useUserSWRContextKey".'); 9 | } 10 | 11 | return `swr::${uuid || 'unknown'}:${key.trim()}`; 12 | }; 13 | -------------------------------------------------------------------------------- /resources/scripts/plugins/useWindowDimensions.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | 3 | function getWindowDimensions () { 4 | const { innerWidth: width, innerHeight: height } = window; 5 | return { width, height }; 6 | } 7 | 8 | export default function useWindowDimensions () { 9 | const [ windowDimensions, setWindowDimensions ] = useState(getWindowDimensions()); 10 | 11 | useEffect(() => { 12 | function handleResize () { 13 | setWindowDimensions(getWindowDimensions()); 14 | } 15 | 16 | window.addEventListener('resize', handleResize); 17 | 18 | return () => window.removeEventListener('resize', handleResize); 19 | }, []); 20 | 21 | return windowDimensions; 22 | } 23 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/scripts/theme.ts: -------------------------------------------------------------------------------- 1 | import { BreakpointFunction, createBreakpoint } from 'styled-components-breakpoint'; 2 | 3 | type Breakpoints = 'xs' | 'sm' | 'md' | 'lg' | 'xl'; 4 | export const breakpoint: BreakpointFunction = createBreakpoint({ 5 | xs: 0, 6 | sm: 640, 7 | md: 768, 8 | lg: 1024, 9 | xl: 1280, 10 | }); 11 | -------------------------------------------------------------------------------- /resources/views/layouts/scripts.blade.php: -------------------------------------------------------------------------------- 1 | {{-- Just here as a binder for dynamically rendered content. --}} 2 | -------------------------------------------------------------------------------- /resources/views/partials/admin/credits/nav.blade.php: -------------------------------------------------------------------------------- 1 | @section('credits::nav') 2 | 3 | 4 | 5 | 6 | Config 7 | Store 8 | Payments 9 | 10 | 11 | 12 | 13 | @endsection 14 | -------------------------------------------------------------------------------- /resources/views/partials/admin/settings/notice.blade.php: -------------------------------------------------------------------------------- 1 | @section('settings::notice') 2 | @if(config('pterodactyl.load_environment_only', false)) 3 | 4 | 5 | 6 | Your Panel is currently configured to read settings from the environment only. You will need to set APP_ENVIRONMENT_ONLY=false in your environment file in order to load settings dynamically. 7 | 8 | 9 | 10 | @endif 11 | @endsection 12 | -------------------------------------------------------------------------------- /resources/views/partials/admin/users/nav.blade.php: -------------------------------------------------------------------------------- 1 | @section('users::nav') 2 | 3 | 4 | 5 | 6 | Profile 7 | Resources 8 | 9 | 10 | 11 | 12 | @endsection 13 | -------------------------------------------------------------------------------- /resources/views/templates/auth/core.blade.php: -------------------------------------------------------------------------------- 1 | @extends('templates/wrapper', [ 2 | 'css' => ['body' => 'bg-neutral-900'] 3 | ]) 4 | 5 | @section('container') 6 | 7 | @endsection 8 | -------------------------------------------------------------------------------- /resources/views/templates/base/core.blade.php: -------------------------------------------------------------------------------- 1 | @extends('templates/wrapper', [ 2 | 'css' => ['body' => 'bg-neutral-800'], 3 | ]) 4 | 5 | @section('container') 6 | 7 | 8 | @endsection 9 | -------------------------------------------------------------------------------- /resources/views/vendor/notifications/email-plain.blade.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}/{namespace}.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !services/* 4 | packs/**/* 5 | services/.bak/* 6 | !packs/.githold 7 | -------------------------------------------------------------------------------- /storage/app/packs/.githold: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jexactyl/Jexactyl-v2-Archive/977db25638a3d09bf9e87a0f950e27824d91ffaa/storage/app/packs/.githold -------------------------------------------------------------------------------- /storage/clockwork/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | compiled.php 4 | services.json 5 | events.scanned.php 6 | routes.scanned.php 7 | down 8 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Unit/Http/Middleware/MiddlewareTestCase.php: -------------------------------------------------------------------------------- 1 | buildRequestMock(); 24 | } 25 | } 26 | --------------------------------------------------------------------------------
APP_ENVIRONMENT_ONLY=false