├── public ├── favicon.ico ├── robots.txt ├── favicon │ ├── favicon.ico │ ├── apple-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── ms-icon-70x70.png │ ├── apple-icon-57x57.png │ ├── apple-icon-60x60.png │ ├── apple-icon-72x72.png │ ├── apple-icon-76x76.png │ ├── ms-icon-144x144.png │ ├── ms-icon-150x150.png │ ├── ms-icon-310x310.png │ ├── android-icon-36x36.png │ ├── android-icon-48x48.png │ ├── android-icon-72x72.png │ ├── android-icon-96x96.png │ ├── apple-icon-114x114.png │ ├── apple-icon-120x120.png │ ├── apple-icon-144x144.png │ ├── apple-icon-152x152.png │ ├── apple-icon-180x180.png │ ├── android-icon-144x144.png │ ├── android-icon-192x192.png │ ├── apple-icon-precomposed.png │ └── browserconfig.xml ├── build │ └── assets │ │ ├── index-BdQq_4o_.js │ │ ├── useQuery-CID0swRD.js │ │ ├── index-CgKzO4Xj.js │ │ ├── header-container-BE9T-U8A.js │ │ ├── site-helper-CrIeK8sC.js │ │ ├── container-0BVhud2R.js │ │ ├── index-DYeKMMEx.js │ │ ├── skeleton-DmQJ5Jny.js │ │ ├── input-error-DDv3evJL.js │ │ ├── status-oOGOnSAH.js │ │ ├── heading-CrC3U2Cb.js │ │ ├── check-H-rc56N8.js │ │ ├── chevron-up-CkgKxk1W.js │ │ ├── play-DBWaixY0.js │ │ ├── chevron-down-BFg3pjLN.js │ │ ├── chevron-left-CNHYS2Rp.js │ │ ├── chevron-right-BCtMwjZq.js │ │ ├── loader-circle-BJeq5FiY.js │ │ ├── plus-D751r8cW.js │ │ ├── cloud-2IT3iR1-.js │ │ ├── text-link-BdVdM4qt.js │ │ ├── search-SeYBnAhi.js │ │ ├── chevrons-up-down-C_9lshW_.js │ │ ├── circle-check-C5ooGkJD.js │ │ ├── index-BIIQn21O.js │ │ ├── export-DVXz8Gr6.js │ │ ├── lock-C91yC-Vq.js │ │ ├── ellipsis-CV-QbUhm.js │ │ ├── globe-BgYtBYj_.js │ │ ├── ellipsis-vertical-CyajjklM.js │ │ ├── trash-CU_5rEP3.js │ │ ├── database-ByFt5wpB.js │ │ ├── form-h1GzMbZM.js │ │ ├── eye-NVKf5C3O.js │ │ ├── download-DRyR4IfQ.js │ │ ├── triangle-alert-cIqJ3BmP.js │ │ ├── users-CWbfDbF5.js │ │ ├── refresh-cw-v4O_-xG6.js │ │ ├── index-l2mI7SCD.js │ │ ├── check-updates-BIqGn_DG.js │ │ ├── index-DUU4w66S.js │ │ ├── logs-B4d6Djcu.js │ │ ├── columns-Mgli88YL.js │ │ └── textarea-CW5NSbOn.js ├── api-docs │ ├── swagger-ui │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── index.css │ │ └── swagger-initializer.js │ └── openapi │ │ ├── schemas │ │ ├── ErrorResponse.yaml │ │ ├── ValidationError.yaml │ │ ├── Project.yaml │ │ └── ProjectUser.yaml │ │ └── base.yaml └── vendor │ └── log-viewer │ ├── img │ ├── log-viewer-32.png │ ├── log-viewer-64.png │ └── log-viewer-128.png │ └── mix-manifest.json ├── database ├── .gitignore ├── seeders │ ├── UsersSeeder.php │ └── CronJobsSeeder.php ├── migrations │ ├── 2023_07_21_210213_update_firewall_rules_table.php │ ├── 2025_01_25_193815_drop_telescope_tables.php │ ├── 2025_03_16_081225_rename_queues_to_workers.php │ ├── 2024_10_06_160213_add_soft_deletes_to_ssh_keys.php │ ├── 2023_08_17_231824_update_backups_table.php │ ├── 2024_10_04_190341_add_soft_deletes_to_databases.php │ ├── 2025_01_29_192733_add_email_to_ssls_table.php │ ├── 2024_10_06_091631_add_log_id_to_ssls.php │ ├── 2025_06_13_162729_update_servers_table.php │ ├── 2025_06_14_111059_add_name_to_workers_table.php │ └── 2023_10_01_120250_create_projects_table.php └── factories │ ├── ServerLogFactory.php │ ├── SshKeyFactory.php │ ├── WorkflowRunFactory.php │ ├── BackupFactory.php │ ├── BackupFileFactory.php │ ├── DatabaseFactory.php │ ├── ProjectFactory.php │ ├── ScriptFactory.php │ ├── NotificationChannelFactory.php │ └── ServiceFactory.php ├── resources ├── views │ ├── vendor │ │ └── scramble │ │ │ └── .gitkeep │ ├── ssh │ │ ├── os │ │ │ ├── delete-file.blade.php │ │ │ ├── get-public-key.blade.php │ │ │ ├── read-ssh-key.blade.php │ │ │ ├── tail.blade.php │ │ │ ├── reboot.blade.php │ │ │ ├── read-file.blade.php │ │ │ ├── generate-ssh-key.blade.php │ │ │ ├── download.blade.php │ │ │ ├── run-script.blade.php │ │ │ ├── delete-isolated-user.blade.php │ │ │ ├── deploy-ssh-key.blade.php │ │ │ ├── available-updates.blade.php │ │ │ ├── upgrade.blade.php │ │ │ ├── edit-file.blade.php │ │ │ ├── delete-ssh-key.blade.php │ │ │ ├── install-dependencies.blade.php │ │ │ ├── resource-info.blade.php │ │ │ ├── extract.blade.php │ │ │ └── cleanup.blade.php │ │ ├── storage │ │ │ ├── local │ │ │ │ └── download.blade.php │ │ │ ├── ftp │ │ │ │ ├── upload.blade.php │ │ │ │ ├── download.blade.php │ │ │ │ └── delete-file.blade.php │ │ │ └── dropbox │ │ │ │ ├── delete-file.blade.php │ │ │ │ ├── download.blade.php │ │ │ │ └── upload.blade.php │ │ ├── services │ │ │ ├── webserver │ │ │ │ ├── caddy │ │ │ │ │ ├── get-vhost.blade.php │ │ │ │ │ ├── vhost-blocks │ │ │ │ │ │ ├── reverse-proxy.blade.php │ │ │ │ │ │ ├── core.blade.php │ │ │ │ │ │ ├── force-ssl.blade.php │ │ │ │ │ │ ├── port.blade.php │ │ │ │ │ │ └── php.blade.php │ │ │ │ │ ├── create-path.blade.php │ │ │ │ │ ├── vhost.blade.php │ │ │ │ │ ├── delete-site.blade.php │ │ │ │ │ ├── create-vhost.blade.php │ │ │ │ │ ├── change-php-version.blade.php │ │ │ │ │ ├── uninstall-caddy.blade.php │ │ │ │ │ ├── create-custom-ssl.blade.php │ │ │ │ │ └── caddy-systemd.blade.php │ │ │ │ └── nginx │ │ │ │ │ ├── get-vhost.blade.php │ │ │ │ │ ├── create-path.blade.php │ │ │ │ │ ├── delete-site.blade.php │ │ │ │ │ ├── vhost-blocks │ │ │ │ │ ├── laravel-octane-map.blade.php │ │ │ │ │ ├── force-ssl.blade.php │ │ │ │ │ ├── port.blade.php │ │ │ │ │ ├── core.blade.php │ │ │ │ │ ├── reverse-proxy.blade.php │ │ │ │ │ └── php.blade.php │ │ │ │ │ ├── install-nginx.blade.php │ │ │ │ │ ├── create-letsencrypt-ssl.blade.php │ │ │ │ │ ├── create-vhost.blade.php │ │ │ │ │ ├── change-php-version.blade.php │ │ │ │ │ ├── vhost.blade.php │ │ │ │ │ ├── uninstall-nginx.blade.php │ │ │ │ │ └── create-custom-ssl.blade.php │ │ │ ├── database │ │ │ │ ├── mysql │ │ │ │ │ ├── get-charsets.blade.php │ │ │ │ │ ├── delete.blade.php │ │ │ │ │ ├── create.blade.php │ │ │ │ │ ├── unlink.blade.php │ │ │ │ │ ├── get-db-list.blade.php │ │ │ │ │ ├── delete-user.blade.php │ │ │ │ │ ├── create-user.blade.php │ │ │ │ │ ├── get-users-list.blade.php │ │ │ │ │ ├── backup.blade.php │ │ │ │ │ ├── restore.blade.php │ │ │ │ │ └── update-user.blade.php │ │ │ │ ├── mariadb │ │ │ │ │ ├── get-charsets.blade.php │ │ │ │ │ ├── delete.blade.php │ │ │ │ │ ├── create.blade.php │ │ │ │ │ ├── unlink.blade.php │ │ │ │ │ ├── delete-user.blade.php │ │ │ │ │ ├── get-db-list.blade.php │ │ │ │ │ ├── uninstall.blade.php │ │ │ │ │ ├── create-user.blade.php │ │ │ │ │ ├── get-users-list.blade.php │ │ │ │ │ ├── backup.blade.php │ │ │ │ │ ├── restore.blade.php │ │ │ │ │ ├── install-1011.blade.php │ │ │ │ │ ├── install-103.blade.php │ │ │ │ │ ├── install-104.blade.php │ │ │ │ │ ├── install-106.blade.php │ │ │ │ │ ├── install-114.blade.php │ │ │ │ │ └── update-user.blade.php │ │ │ │ └── postgresql │ │ │ │ │ ├── delete.blade.php │ │ │ │ │ ├── delete-user.blade.php │ │ │ │ │ ├── create.blade.php │ │ │ │ │ ├── create-user.blade.php │ │ │ │ │ ├── update-user.blade.php │ │ │ │ │ ├── get-db-list.blade.php │ │ │ │ │ ├── restore.blade.php │ │ │ │ │ ├── get-charsets.blade.php │ │ │ │ │ ├── get-users-list.blade.php │ │ │ │ │ └── backup.blade.php │ │ │ ├── php │ │ │ │ ├── remove-fpm-pool.blade.php │ │ │ │ ├── install-php-extension.blade.php │ │ │ │ ├── install-composer.blade.php │ │ │ │ ├── change-default-php.blade.php │ │ │ │ ├── update-php-settings.blade.php │ │ │ │ └── uninstall-php.blade.php │ │ │ ├── process-manager │ │ │ │ └── supervisor │ │ │ │ │ ├── start-worker.blade.php │ │ │ │ │ ├── stop-worker.blade.php │ │ │ │ │ ├── restart-worker.blade.php │ │ │ │ │ ├── install-supervisor.blade.php │ │ │ │ │ ├── restart-all-workers.blade.php │ │ │ │ │ ├── restart-workers.blade.php │ │ │ │ │ ├── uninstall-supervisor.blade.php │ │ │ │ │ ├── worker.blade.php │ │ │ │ │ └── delete-worker.blade.php │ │ │ ├── redis │ │ │ │ ├── install.blade.php │ │ │ │ └── uninstall.blade.php │ │ │ ├── firewall │ │ │ │ └── ufw │ │ │ │ │ ├── clear-backups.blade.php │ │ │ │ │ ├── backup-rules.blade.php │ │ │ │ │ └── restore-rules.blade.php │ │ │ └── monitoring │ │ │ │ └── vito-agent │ │ │ │ └── uninstall.blade.php │ │ ├── modern-deployment │ │ │ ├── release.blade.php │ │ │ ├── link-resources.blade.php │ │ │ └── disable.blade.php │ │ ├── git │ │ │ ├── fetch-origin.blade.php │ │ │ └── checkout.blade.php │ │ ├── cron │ │ │ └── update.blade.php │ │ └── composer │ │ │ └── composer-install.blade.php │ └── emails │ │ └── project-invitation.blade.php ├── js │ ├── types │ │ ├── vite-env.d.ts │ │ ├── global.d.ts │ │ ├── workflow-node-data.d.ts │ │ ├── api-key.d.ts │ │ ├── project-user.d.ts │ │ ├── server-template.d.ts │ │ ├── dns-provider.d.ts │ │ ├── source-control.d.ts │ │ ├── storage-provider.d.ts │ │ ├── ssh-key.d.ts │ │ ├── command.d.ts │ │ ├── load-balancer-server.d.ts │ │ ├── notification-channel.d.ts │ │ ├── server-log.d.ts │ │ ├── domain.d.ts │ │ ├── project.d.ts │ │ ├── server-provider.d.ts │ │ ├── workflow-action.d.ts │ │ ├── cronjob.d.ts │ │ ├── database.d.ts │ │ ├── workflow-run.d.ts │ │ ├── redirect.d.ts │ │ ├── deployment-script.d.ts │ │ ├── workflow.d.ts │ │ ├── database-user.d.ts │ │ ├── dns-record.d.ts │ │ ├── firewall.d.ts │ │ ├── script.d.ts │ │ ├── worker.d.ts │ │ ├── ssl.d.ts │ │ ├── command-execution.d.ts │ │ ├── user.d.ts │ │ ├── backup-file.d.ts │ │ ├── metric.d.ts │ │ ├── dynamic-field-config.d.ts │ │ ├── script-execution.d.ts │ │ ├── plugin.d.ts │ │ └── deployment.d.ts │ ├── components │ │ ├── header-container.tsx │ │ ├── ui │ │ │ ├── skeleton.tsx │ │ │ ├── icon.tsx │ │ │ └── input-error.tsx │ │ ├── app-logo.tsx │ │ ├── container.tsx │ │ ├── date-time.tsx │ │ ├── heading-small.tsx │ │ ├── heading.tsx │ │ ├── form-successful.tsx │ │ ├── icon.tsx │ │ ├── app-logo-icon-html.tsx │ │ └── text-link.tsx │ ├── hooks │ │ ├── use-mobile-navigation.ts │ │ ├── use-initials.tsx │ │ ├── use-mobile.tsx │ │ └── use-page-active.tsx │ ├── pages │ │ ├── servers │ │ │ └── components │ │ │ │ └── status.tsx │ │ ├── vito-settings │ │ │ └── components │ │ │ │ └── export.tsx │ │ └── plugins │ │ │ └── components │ │ │ └── check-updates.tsx │ ├── stores │ │ └── useInputFocus.ts │ ├── icons │ │ └── vito.tsx │ └── lib │ │ ├── site-helper.ts │ │ └── event-bus.tsx ├── svg │ ├── logo.png │ ├── email.svg │ ├── force-ssl-enabled.svg │ ├── force-ssl-disabled.svg │ ├── memory.svg │ ├── book-open.svg │ ├── remote-monitor.svg │ ├── hetzner.svg │ ├── monitoring.svg │ ├── vitomonitor.svg │ ├── custom.svg │ ├── server.svg │ ├── ftp.svg │ ├── ufw.svg │ ├── local.svg │ └── disk.svg └── deployment-scripts │ ├── nodejs.sh │ └── laravel.sh ├── bootstrap └── cache │ └── .gitignore ├── storage ├── logs │ └── .gitignore ├── plugins │ └── .gitignore ├── app │ ├── public │ │ └── .gitignore │ └── .gitignore └── framework │ ├── testing │ └── .gitignore │ ├── views │ └── .gitignore │ ├── cache │ ├── data │ │ └── .gitignore │ └── .gitignore │ ├── sessions │ └── .gitignore │ └── .gitignore ├── Makefile ├── docker ├── php.ini └── supervisord.conf ├── pint.json ├── app ├── Exceptions │ ├── SSHCommandError.php │ ├── SSHUploadFailed.php │ ├── SSHConnectionError.php │ ├── SSLCreationException.php │ ├── SSHAuthenticationError.php │ ├── AppError.php │ ├── RepositoryNotFound.php │ ├── FailedToDeleteServer.php │ ├── FailedToDeployGitKey.php │ ├── GitRepositoryNotFound.php │ ├── ServerProviderError.php │ ├── CouldNotConnectToProvider.php │ ├── RepositoryPermissionDenied.php │ ├── ServerInstallationFailed.php │ ├── ServiceInstallationFailed.php │ ├── FailedToDeployGitHook.php │ ├── FailedToDestroyGitHook.php │ ├── SSHError.php │ └── SourceControlIsNotConnected.php ├── Contracts │ └── VitoEnum.php ├── Services │ └── Firewall │ │ └── Firewall.php ├── Actions │ ├── Domain │ │ └── RemoveDomain.php │ ├── Worker │ │ ├── DeleteWorker.php │ │ └── GetWorkerLogs.php │ ├── DNSProvider │ │ └── DeleteDNSProvider.php │ ├── User │ │ └── PasswordValidationRules.php │ ├── Plugins │ │ ├── ClearLogs.php │ │ └── Github │ │ │ └── UpdateGithubPlugin.php │ ├── SSL │ │ ├── DeactivateSSL.php │ │ └── ActivateSSL.php │ ├── Server │ │ ├── Update.php │ │ └── RebootServer.php │ ├── Redirect │ │ └── DeleteRedirect.php │ ├── SourceControl │ │ └── DeleteSourceControl.php │ ├── ServerProvider │ │ └── DeleteServerProvider.php │ ├── StorageProvider │ │ └── DeleteStorageProvider.php │ ├── Database │ │ └── DeleteDatabaseUser.php │ └── ServerLog │ │ └── UpdateLog.php ├── SSH │ ├── Storage │ │ ├── AbstractStorage.php │ │ └── Storage.php │ └── OS │ │ ├── Cron.php │ │ └── Composer.php ├── SiteFeatures │ ├── Action.php │ ├── ActionInterface.php │ └── FeatureInterface.php ├── ServerFeatures │ ├── Action.php │ ├── ActionInterface.php │ └── FeatureInterface.php ├── Http │ ├── Controllers │ │ ├── Controller.php │ │ ├── HomeController.php │ │ ├── API │ │ │ └── HealthController.php │ │ ├── SettingController.php │ │ └── Admin │ │ │ └── AdminController.php │ └── Middleware │ │ ├── EncryptCookies.php │ │ ├── MustBeAdminMiddleware.php │ │ ├── VerifyCsrfToken.php │ │ ├── PreventRequestsDuringMaintenance.php │ │ ├── TrimStrings.php │ │ ├── TrustHosts.php │ │ ├── Authenticate.php │ │ ├── ValidateSignature.php │ │ └── HandleAppearance.php ├── StorageProviders │ ├── AbstractStorageProvider.php │ └── StorageProvider.php ├── WorkflowActions │ ├── Site │ │ ├── CreatePHPMyAdminSite.php │ │ ├── CreateLoadBalancerSite.php │ │ ├── CreatePHPBlankSite.php │ │ └── CreateNodeJsSite.php │ └── WorkflowActionInterface.php ├── Enums │ ├── PHPIniType.php │ ├── BackupType.php │ ├── UserRole.php │ ├── LoadBalancerMethod.php │ ├── SslType.php │ ├── SshKeyStatus.php │ ├── DatabaseUserPermission.php │ ├── DeploymentStatus.php │ ├── WorkflowRunStatus.php │ ├── CommandExecutionStatus.php │ └── ScriptExecutionStatus.php ├── Facades │ ├── Notifier.php │ └── Plugins.php ├── NotificationChannels │ ├── AbstractNotificationChannel.php │ └── Email │ │ └── NotificationMail.php ├── Plugins │ └── Interfaces │ │ └── PluginInterface.php ├── DTOs │ └── GitHub │ │ └── AuthorDto.php ├── Notifications │ ├── NotificationInterface.php │ └── GenericNotification.php ├── ValidationRules │ ├── RestrictedIPAddressesRule.php │ ├── DomainRule.php │ └── SshKeyRule.php ├── Traits │ ├── NormalizesWebDirectory.php │ └── HasProjectThroughServer.php ├── Helpers │ └── Notifier.php └── Models │ └── PersonalAccessToken.php ├── CONTRIBUTING.md ├── tests ├── Unit │ ├── Plugins │ │ └── Artifacts │ │ │ └── VitoOctanePlugin-1.0.2.zip │ └── NotificationChannels │ │ └── TestNotification.php ├── CreatesApplication.php └── Feature │ └── VitoSettingsTest.php ├── config ├── site.php ├── workflow.php ├── service.php ├── dns-provider.php ├── server-provider.php ├── source-control.php ├── storage-provider.php ├── notification-channel.php └── web.php ├── scripts └── post-update.sh ├── .mcp.json ├── .gitattributes ├── phpstan.neon ├── .prettierignore ├── .env.prod ├── .env.example ├── .env.sail ├── .editorconfig ├── components.json ├── lang └── en.json ├── SECURITY.md └── rector.php /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /resources/views/vendor/scramble/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/plugins/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | start: 2 | ./sail up 3 | 4 | stop: 5 | ./sail down 6 | -------------------------------------------------------------------------------- /resources/views/ssh/os/delete-file.blade.php: -------------------------------------------------------------------------------- 1 | rm -rf {{ $path }} 2 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /resources/views/ssh/os/get-public-key.blade.php: -------------------------------------------------------------------------------- 1 | cat ~/.ssh/id_rsa.pub 2 | -------------------------------------------------------------------------------- /resources/js/types/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /resources/views/ssh/os/read-ssh-key.blade.php: -------------------------------------------------------------------------------- 1 | cat ~/.ssh/{{ $name }}.pub 2 | -------------------------------------------------------------------------------- /resources/views/ssh/os/tail.blade.php: -------------------------------------------------------------------------------- 1 | sudo tail -n {{ $lines }} {{ $path }} 2 | -------------------------------------------------------------------------------- /resources/views/ssh/storage/local/download.blade.php: -------------------------------------------------------------------------------- 1 | cp {{ $src }} {{ $dest }} 2 | -------------------------------------------------------------------------------- /resources/views/ssh/os/reboot.blade.php: -------------------------------------------------------------------------------- 1 | echo "Rebooting..." 2 | 3 | sudo reboot 4 | -------------------------------------------------------------------------------- /resources/views/ssh/os/read-file.blade.php: -------------------------------------------------------------------------------- 1 | [ -f {{ $path }} ] && sudo cat {{ $path }} 2 | -------------------------------------------------------------------------------- /docker/php.ini: -------------------------------------------------------------------------------- 1 | [PHP] 2 | post_max_size = 2G 3 | upload_max_filesize = 1G 4 | memory_limit = 2G 5 | -------------------------------------------------------------------------------- /resources/svg/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/resources/svg/logo.png -------------------------------------------------------------------------------- /public/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/favicon.ico -------------------------------------------------------------------------------- /public/build/assets/index-BdQq_4o_.js: -------------------------------------------------------------------------------- 1 | function c(a,[t,n]){return Math.min(n,Math.max(t,a))}export{c}; 2 | -------------------------------------------------------------------------------- /resources/views/ssh/os/generate-ssh-key.blade.php: -------------------------------------------------------------------------------- 1 | ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/{{ $name }} 2 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/caddy/get-vhost.blade.php: -------------------------------------------------------------------------------- 1 | cat /etc/caddy/sites-available/{{ $domain }} -------------------------------------------------------------------------------- /public/favicon/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon.png -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/get-vhost.blade.php: -------------------------------------------------------------------------------- 1 | cat /etc/nginx/sites-available/{{ $domain }} 2 | -------------------------------------------------------------------------------- /pint.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "laravel", 3 | "exclude": [ 4 | "resources/views/ssh" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /public/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/favicon-96x96.png -------------------------------------------------------------------------------- /public/favicon/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/ms-icon-70x70.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-57x57.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-60x60.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-72x72.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-76x76.png -------------------------------------------------------------------------------- /public/favicon/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/ms-icon-144x144.png -------------------------------------------------------------------------------- /public/favicon/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/ms-icon-150x150.png -------------------------------------------------------------------------------- /public/favicon/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/ms-icon-310x310.png -------------------------------------------------------------------------------- /public/favicon/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/android-icon-36x36.png -------------------------------------------------------------------------------- /public/favicon/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/android-icon-48x48.png -------------------------------------------------------------------------------- /public/favicon/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/android-icon-72x72.png -------------------------------------------------------------------------------- /public/favicon/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/android-icon-96x96.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-114x114.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-120x120.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-144x144.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-152x152.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-180x180.png -------------------------------------------------------------------------------- /public/favicon/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/android-icon-144x144.png -------------------------------------------------------------------------------- /public/favicon/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/android-icon-192x192.png -------------------------------------------------------------------------------- /public/favicon/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/favicon/apple-icon-precomposed.png -------------------------------------------------------------------------------- /resources/views/ssh/os/download.blade.php: -------------------------------------------------------------------------------- 1 | if ! wget {{ $url }} -O {{ $path }}; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | -------------------------------------------------------------------------------- /public/api-docs/swagger-ui/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/api-docs/swagger-ui/favicon-16x16.png -------------------------------------------------------------------------------- /public/api-docs/swagger-ui/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/api-docs/swagger-ui/favicon-32x32.png -------------------------------------------------------------------------------- /public/vendor/log-viewer/img/log-viewer-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/vendor/log-viewer/img/log-viewer-32.png -------------------------------------------------------------------------------- /public/vendor/log-viewer/img/log-viewer-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/vendor/log-viewer/img/log-viewer-64.png -------------------------------------------------------------------------------- /public/build/assets/useQuery-CID0swRD.js: -------------------------------------------------------------------------------- 1 | import{u as r,l as u}from"./useBaseQuery-CHNhq3X1.js";function a(e,s){return r(e,u)}export{a as u}; 2 | -------------------------------------------------------------------------------- /public/vendor/log-viewer/img/log-viewer-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitodeploy/vito/HEAD/public/vendor/log-viewer/img/log-viewer-128.png -------------------------------------------------------------------------------- /resources/views/ssh/os/run-script.blade.php: -------------------------------------------------------------------------------- 1 | if ! cd {{ $path }}; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | {!! $script !!} 6 | -------------------------------------------------------------------------------- /app/Exceptions/SSHCommandError.php: -------------------------------------------------------------------------------- 1 | [ 5 | // this will be automatically registered by the SiteTypeServiceProvider 6 | ], 7 | ]; 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mariadb/get-charsets.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mariadb -e "SHOW COLLATION;"; 2 | then 3 | echo 'VITO_SSH_ERROR' && exit 1 4 | fi 5 | -------------------------------------------------------------------------------- /app/Exceptions/AppError.php: -------------------------------------------------------------------------------- 1 | [ 5 | // this will be automatically registered by the WorkflowServiceProvider 6 | ], 7 | ]; 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/php/remove-fpm-pool.blade.php: -------------------------------------------------------------------------------- 1 | sudo rm -f /etc/php/{{ $version }}/fpm/pool.d/{{ $user }}.conf 2 | sudo service php{{ $version }}-fpm restart 3 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/caddy/vhost-blocks/reverse-proxy.blade.php: -------------------------------------------------------------------------------- 1 | #[reverse-proxy] 2 | reverse_proxy localhost:{{ $site->port }} 3 | #[/reverse-proxy] 4 | -------------------------------------------------------------------------------- /config/service.php: -------------------------------------------------------------------------------- 1 | [ 5 | // this will be automatically registered by the ServiceTypeServiceProvider 6 | ], 7 | ]; 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/process-manager/supervisor/start-worker.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo supervisorctl start {{ $id }}:*; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | -------------------------------------------------------------------------------- /resources/views/ssh/services/process-manager/supervisor/stop-worker.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo supervisorctl stop {{ $id }}:*; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | -------------------------------------------------------------------------------- /resources/views/ssh/storage/ftp/upload.blade.php: -------------------------------------------------------------------------------- 1 | curl {{ $passive }} -T "{{ $src }}" -u "{{ $username }}:{{ $password }}" ftp{{ $ssl }}://{{ $host }}:{{ $port }}/{{ $dest }} 2 | -------------------------------------------------------------------------------- /config/dns-provider.php: -------------------------------------------------------------------------------- 1 | [ 5 | // this will be automatically registered by the DNSProviderServiceProvider 6 | ], 7 | ]; 8 | -------------------------------------------------------------------------------- /config/server-provider.php: -------------------------------------------------------------------------------- 1 | [ 5 | // this will be automatically registered by the ServerServiceProvider 6 | ], 7 | ]; 8 | -------------------------------------------------------------------------------- /config/source-control.php: -------------------------------------------------------------------------------- 1 | [ 5 | // this will be automatically registered by the StorageServiceProvider 6 | ], 7 | ]; 8 | -------------------------------------------------------------------------------- /config/storage-provider.php: -------------------------------------------------------------------------------- 1 | [ 5 | // this will be automatically registered by the StorageServiceProvider 6 | ], 7 | ]; 8 | -------------------------------------------------------------------------------- /public/build/assets/index-CgKzO4Xj.js: -------------------------------------------------------------------------------- 1 | import{r as t}from"./app-8WgsWSPq.js";var e=t.createContext(void 0);function i(r){const o=t.useContext(e);return r||o||"ltr"}export{i as u}; 2 | -------------------------------------------------------------------------------- /resources/views/ssh/services/process-manager/supervisor/restart-worker.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo supervisorctl restart {{ $id }}:*; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | -------------------------------------------------------------------------------- /resources/views/ssh/storage/ftp/download.blade.php: -------------------------------------------------------------------------------- 1 | curl {{ $passive }} -u "{{ $username }}:{{ $password }}" ftp{{ $ssl }}://{{ $host }}:{{ $port }}/{{ $src }} -o "{{ $dest }}" 2 | -------------------------------------------------------------------------------- /config/notification-channel.php: -------------------------------------------------------------------------------- 1 | [ 5 | // this will be automatically registered by the StorageServiceProvider 6 | ], 7 | ]; 8 | -------------------------------------------------------------------------------- /resources/views/ssh/modern-deployment/release.blade.php: -------------------------------------------------------------------------------- 1 | ln -sfn {{ $releasePath }} {{ $site->basePath() }}/current 2 | 3 | echo "Version {{ basename($releasePath) }} activated! 🎉" 4 | -------------------------------------------------------------------------------- /resources/views/ssh/os/delete-isolated-user.blade.php: -------------------------------------------------------------------------------- 1 | sudo gpasswd -d {{ $serverUser }} {{ $user }} 2 | sudo userdel -r -f "{{ $user }}" 3 | echo "User {{ $user }} has been deleted." 4 | -------------------------------------------------------------------------------- /resources/views/ssh/storage/ftp/delete-file.blade.php: -------------------------------------------------------------------------------- 1 | curl {{ $passive }} -u "{{ $username }}:{{ $password }}" ftp{{ $ssl }}://{{ $host }}:{{ $port }}/{{ $src }} -Q "DELE /{{ $src }}" 2 | -------------------------------------------------------------------------------- /app/Exceptions/RepositoryNotFound.php: -------------------------------------------------------------------------------- 1 | domain }} 3 | import compression 4 | import security_headers 5 | #[/core] 6 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | compiled.php 2 | config.php 3 | down 4 | events.scanned.php 5 | maintenance.php 6 | routes.php 7 | routes.scanned.php 8 | schedule-* 9 | services.json 10 | -------------------------------------------------------------------------------- /app/Exceptions/FailedToDeleteServer.php: -------------------------------------------------------------------------------- 1 | domain }} {{ $site->getAliasesString() }} { 2 | #[main] 3 | @foreach($main ?? [] as $main) 4 | {{ $main }} 5 | @endforeach 6 | #[/main] 7 | } 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/caddy/vhost-blocks/force-ssl.blade.php: -------------------------------------------------------------------------------- 1 | #[force-ssl] 2 | @if ($site->activeSsl && $site->force_ssl) 3 | redir @http https://{host}{uri} permanent 4 | @endif 5 | #[/force-ssl] 6 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/caddy/vhost-blocks/port.blade.php: -------------------------------------------------------------------------------- 1 | #[port] 2 | @if ($site->activeSsl) 3 | tls {{ $site->activeSsl->certificate_path }} {{ $site->activeSsl->pk_path }} 4 | @endif 5 | #[/port] 6 | -------------------------------------------------------------------------------- /public/api-docs/openapi/base.yaml: -------------------------------------------------------------------------------- 1 | components: 2 | securitySchemes: 3 | bearerAuth: 4 | type: http 5 | scheme: bearer 6 | bearerFormat: JWT 7 | description: Sanctum bearer token authentication 8 | -------------------------------------------------------------------------------- /scripts/post-update.sh: -------------------------------------------------------------------------------- 1 | # post-update script is here to cover extra commands in case of an update requires it. 2 | echo "Running post-update script..." 3 | 4 | echo "Removing legacy plugins..." 5 | rm -rf storage/plugins/*/ 6 | -------------------------------------------------------------------------------- /resources/js/types/api-key.d.ts: -------------------------------------------------------------------------------- 1 | export interface ApiKey { 2 | id: number; 3 | name: string; 4 | permissions: string[]; 5 | created_at: string; 6 | updated_at: string; 7 | 8 | [key: string]: unknown; 9 | } 10 | -------------------------------------------------------------------------------- /resources/views/ssh/os/deploy-ssh-key.blade.php: -------------------------------------------------------------------------------- 1 | mkdir -p ~/.ssh 2 | chmod 700 ~/.ssh 3 | if ! echo '{!! $key !!}' >> ~/.ssh/authorized_keys; then 4 | echo 'VITO_SSH_ERROR' && exit 1 5 | fi 6 | chmod 600 ~/.ssh/authorized_keys 7 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/postgresql/delete.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo -u postgres psql -c "DROP DATABASE \"{{ $name }}\""; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | echo "Database {{ $name }} deleted" 6 | -------------------------------------------------------------------------------- /resources/views/ssh/services/process-manager/supervisor/install-supervisor.blade.php: -------------------------------------------------------------------------------- 1 | sudo DEBIAN_FRONTEND=noninteractive apt-get install supervisor -y 2 | 3 | sudo service supervisor enable 4 | 5 | sudo service supervisor start 6 | -------------------------------------------------------------------------------- /resources/views/ssh/services/process-manager/supervisor/restart-all-workers.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo supervisorctl restart all; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | echo "All workers restarted successfully." 6 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/caddy/delete-site.blade.php: -------------------------------------------------------------------------------- 1 | rm -rf {{ $path }} 2 | 3 | sudo rm /etc/caddy/sites-available/{{ $domain }} 4 | 5 | sudo rm /etc/caddy/sites-enabled/{{ $domain }} 6 | 7 | echo "Site deleted" 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/delete-site.blade.php: -------------------------------------------------------------------------------- 1 | rm -rf {{ $path }} 2 | 3 | sudo rm /etc/nginx/sites-available/{{ $domain }} 4 | 5 | sudo rm /etc/nginx/sites-enabled/{{ $domain }} 6 | 7 | echo "Site deleted" 8 | -------------------------------------------------------------------------------- /resources/deployment-scripts/nodejs.sh: -------------------------------------------------------------------------------- 1 | cd $SITE_PATH 2 | 3 | git pull origin $BRANCH 4 | 5 | npm install 6 | 7 | npm run build 8 | 9 | sudo supervisorctl restart all 10 | 11 | echo "✅ Deployment completed successfully!" 12 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/postgresql/delete-user.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo -u postgres psql -c "DROP USER \"{{ $username }}\""; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | echo "User {{ $username }} deleted" 6 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/vhost-blocks/laravel-octane-map.blade.php: -------------------------------------------------------------------------------- 1 | #[laravel-octane-map] 2 | map $http_upgrade $connection_upgrade { 3 | default upgrade; 4 | '' close; 5 | } 6 | #[/laravel-octane-map] 7 | -------------------------------------------------------------------------------- /config/web.php: -------------------------------------------------------------------------------- 1 | 10, 7 | 8 | 'controllers' => [ 9 | 'servers' => ServerController::class, 10 | ], 11 | ]; 12 | -------------------------------------------------------------------------------- /.mcp.json: -------------------------------------------------------------------------------- 1 | { 2 | "mcpServers": { 3 | "laravel-boost": { 4 | "command": "php", 5 | "args": [ 6 | "artisan", 7 | "boost:mcp" 8 | ] 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /app/Services/Firewall/Firewall.php: -------------------------------------------------------------------------------- 1 | {children}; 5 | } 6 | -------------------------------------------------------------------------------- /public/build/assets/index-DYeKMMEx.js: -------------------------------------------------------------------------------- 1 | import{r as u}from"./app-8WgsWSPq.js";function o(r){const e=u.useRef({value:r,previous:r});return u.useMemo(()=>(e.current.value!==r&&(e.current.previous=e.current.value,e.current.value=r),e.current.previous),[r])}export{o as u}; 2 | -------------------------------------------------------------------------------- /public/build/assets/skeleton-DmQJ5Jny.js: -------------------------------------------------------------------------------- 1 | import{j as o}from"./app-8WgsWSPq.js";import{c as s}from"./utils-DDOqEnVW.js";function r({className:t,...e}){return o.jsx("div",{"data-slot":"skeleton",className:s("bg-accent animate-pulse rounded-md",t),...e})}export{r as S}; 2 | -------------------------------------------------------------------------------- /resources/views/ssh/os/upgrade.blade.php: -------------------------------------------------------------------------------- 1 | sudo DEBIAN_FRONTEND=noninteractive apt-get clean 2 | sudo DEBIAN_FRONTEND=noninteractive apt-get update 3 | sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y 4 | sudo DEBIAN_FRONTEND=noninteractive apt-get autoremove -y 5 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mysql/create.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mysql -e "CREATE DATABASE IF NOT EXISTS {{ $name }} CHARACTER SET '{{ $charset }}' COLLATE '{{ $collation }}'"; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | echo "Command executed" 6 | -------------------------------------------------------------------------------- /app/Actions/Domain/RemoveDomain.php: -------------------------------------------------------------------------------- 1 | delete(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/Actions/Worker/DeleteWorker.php: -------------------------------------------------------------------------------- 1 | delete(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mariadb/create.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mariadb -e "CREATE DATABASE IF NOT EXISTS {{ $name }} CHARACTER SET '{{ $charset }}' COLLATE '{{ $collation }}'"; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | echo "Command executed" 6 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/postgresql/create-user.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo -u postgres psql -c "CREATE ROLE \"{{ $username }}\" WITH LOGIN PASSWORD '{{ $password }}';"; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | echo "User {{ $username }} created" 6 | -------------------------------------------------------------------------------- /resources/views/ssh/services/redis/install.blade.php: -------------------------------------------------------------------------------- 1 | sudo DEBIAN_FRONTEND=noninteractive apt-get install redis-server -y 2 | 3 | sudo sed -i 's/bind 127.0.0.1 ::1/bind 0.0.0.0/g' /etc/redis/redis.conf 4 | 5 | sudo service redis enable 6 | 7 | sudo service redis start 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/create-letsencrypt-ssl.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo certbot certonly --force-renewal --nginx --noninteractive --agree-tos --cert-name {{ $name }} -m {{ $email }} {{ $domains }} --verbose; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | -------------------------------------------------------------------------------- /public/build/assets/input-error-DDv3evJL.js: -------------------------------------------------------------------------------- 1 | import{j as n}from"./app-8WgsWSPq.js";import{c as o}from"./utils-DDOqEnVW.js";function m({message:r,className:t="",...e}){return r?n.jsx("p",{...e,className:o("text-sm text-red-600 dark:text-red-400",t),children:r}):null}export{m as I}; 2 | -------------------------------------------------------------------------------- /resources/js/types/dns-provider.d.ts: -------------------------------------------------------------------------------- 1 | export interface DNSProvider { 2 | id: number; 3 | name: string; 4 | provider: string; 5 | connected: boolean; 6 | project_id: number | null; 7 | global: boolean; 8 | created_at: string; 9 | updated_at: string; 10 | } 11 | -------------------------------------------------------------------------------- /resources/views/ssh/services/php/install-composer.blade.php: -------------------------------------------------------------------------------- 1 | cd ~ 2 | 3 | curl -sS https://getcomposer.org/installer -o composer-setup.php 4 | 5 | sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer 6 | 7 | rm composer-setup.php 8 | 9 | composer 10 | -------------------------------------------------------------------------------- /resources/js/types/source-control.d.ts: -------------------------------------------------------------------------------- 1 | export interface SourceControl { 2 | id: number; 3 | project_id?: number; 4 | global: boolean; 5 | name: string; 6 | provider: string; 7 | created_at: string; 8 | updated_at: string; 9 | 10 | [key: string]: unknown; 11 | } 12 | -------------------------------------------------------------------------------- /resources/views/ssh/services/firewall/ufw/clear-backups.blade.php: -------------------------------------------------------------------------------- 1 | sudo rm -f /tmp/ufw.before.backup 2 | sudo rm -f /tmp/ufw.after.backup 3 | sudo rm -f /tmp/ufw.user.backup 4 | sudo rm -f /tmp/ufw.before6.backup 5 | sudo rm -f /tmp/ufw.after6.backup 6 | sudo rm -f /tmp/ufw.user6.backup 7 | -------------------------------------------------------------------------------- /resources/views/ssh/services/process-manager/supervisor/restart-workers.blade.php: -------------------------------------------------------------------------------- 1 | @foreach($workerIds as $workerId) 2 | if ! sudo supervisorctl restart {{ $workerId }}:*; then 3 | echo 'VITO_SSH_ERROR' && exit 1 4 | fi 5 | @endforeach 6 | 7 | echo "Workers restarted successfully." 8 | -------------------------------------------------------------------------------- /resources/js/types/storage-provider.d.ts: -------------------------------------------------------------------------------- 1 | export interface StorageProvider { 2 | id: number; 3 | project_id?: number; 4 | global: boolean; 5 | name: string; 6 | provider: string; 7 | created_at: string; 8 | updated_at: string; 9 | 10 | [key: string]: unknown; 11 | } 12 | -------------------------------------------------------------------------------- /resources/views/ssh/cron/update.blade.php: -------------------------------------------------------------------------------- 1 | if ! echo '{!! $cron !!}' | sudo -u {{ $user }} crontab -; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo -u {{ $user }} crontab -l; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | echo 'cron updated!' 10 | -------------------------------------------------------------------------------- /resources/views/ssh/storage/dropbox/delete-file.blade.php: -------------------------------------------------------------------------------- 1 | curl --location --request POST 'https://api.dropboxapi.com/2/files/delete_v2' \ 2 | --header 'Authorization: Bearer {{ $token }}' \ 3 | --header 'Content-Type: application/json' \ 4 | --data-raw '{ 5 | "path": "{{ $src }}" 6 | }' 7 | -------------------------------------------------------------------------------- /resources/js/hooks/use-mobile-navigation.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react'; 2 | 3 | export function useMobileNavigation() { 4 | return useCallback(() => { 5 | // Remove pointer-events style from body... 6 | document.body.style.removeProperty('pointer-events'); 7 | }, []); 8 | } 9 | -------------------------------------------------------------------------------- /resources/js/types/ssh-key.d.ts: -------------------------------------------------------------------------------- 1 | import { User } from '@/types/user'; 2 | 3 | export interface SshKey { 4 | id: number; 5 | user?: User; 6 | name: string; 7 | deployment_user?: string; 8 | created_at: string; 9 | updated_at: string; 10 | 11 | [key: string]: unknown; 12 | } 13 | -------------------------------------------------------------------------------- /resources/views/ssh/os/edit-file.blade.php: -------------------------------------------------------------------------------- 1 | @if($sudo) sudo @endif tee {!! $path !!} << 'VITO_SSH_EOF' > /dev/null 2 | {!! $content !!} 3 | VITO_SSH_EOF 4 | 5 | if [ $? -eq 0 ]; then 6 | echo "Successfully wrote to {{ $path }}" 7 | else 8 | echo 'VITO_SSH_ERROR' && exit 1 9 | fi 10 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/caddy/create-vhost.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo ln -s /etc/caddy/sites-available/{{ $domain }} /etc/caddy/sites-enabled/; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo service caddy restart; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/create-vhost.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo ln -s /etc/nginx/sites-available/{{ $domain }} /etc/nginx/sites-enabled/; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo service nginx restart; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /public/build/assets/status-oOGOnSAH.js: -------------------------------------------------------------------------------- 1 | import{j as r}from"./app-8WgsWSPq.js";import{B as o}from"./badge-Lxm3AxQ6.js";/* empty css */import"./utils-DDOqEnVW.js";import"./index-CN-FHsb7.js";function u({server:t}){return r.jsx(o,{variant:t.status_color,children:t.status})}export{u as default}; 2 | -------------------------------------------------------------------------------- /resources/js/pages/servers/components/status.tsx: -------------------------------------------------------------------------------- 1 | import { Server } from '@/types/server'; 2 | import { Badge } from '@/components/ui/badge'; 3 | 4 | export default function ServerStatus({ server }: { server: Server }) { 5 | return {server.status}; 6 | } 7 | -------------------------------------------------------------------------------- /resources/js/types/command.d.ts: -------------------------------------------------------------------------------- 1 | export interface Command { 2 | id: number; 3 | server_id: number; 4 | site_id: number; 5 | name: string; 6 | command: string; 7 | variables: string[]; 8 | created_at: string; 9 | updated_at: string; 10 | 11 | [key: string]: unknown; 12 | } 13 | -------------------------------------------------------------------------------- /resources/js/types/load-balancer-server.d.ts: -------------------------------------------------------------------------------- 1 | export interface LoadBalancerServer { 2 | load_balancer_id: number; 3 | ip: string; 4 | port: number; 5 | weight: string; 6 | backup: boolean; 7 | created_at: string; 8 | updated_at: string; 9 | 10 | [key: string]: unknown; 11 | } 12 | -------------------------------------------------------------------------------- /resources/js/types/notification-channel.d.ts: -------------------------------------------------------------------------------- 1 | export interface NotificationChannel { 2 | id: number; 3 | project_id?: number; 4 | global: boolean; 5 | name: string; 6 | provider: string; 7 | created_at: string; 8 | updated_at: string; 9 | 10 | [key: string]: unknown; 11 | } 12 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mysql/unlink.blade.php: -------------------------------------------------------------------------------- 1 | sudo mysql -e "REVOKE ALL PRIVILEGES, GRANT OPTION FROM '{{ $username }}'@'{{ $host }}'" 2>/dev/null || true 2 | 3 | if ! sudo mysql -e "FLUSH PRIVILEGES"; then 4 | echo 'VITO_SSH_ERROR' && exit 1 5 | fi 6 | 7 | echo "Command executed" 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/postgresql/update-user.blade.php: -------------------------------------------------------------------------------- 1 | @if ($newPassword) 2 | if ! sudo -u postgres psql -c "ALTER ROLE \"{{ $username }}\" WITH PASSWORD '{{ $newPassword }}';"; then 3 | echo 'VITO_SSH_ERROR' && exit 1 4 | fi 5 | @endif 6 | 7 | 8 | echo "User {{ $username }} updated" -------------------------------------------------------------------------------- /resources/views/ssh/storage/dropbox/download.blade.php: -------------------------------------------------------------------------------- 1 | curl -o {{ $dest }} --location --request POST 'https://content.dropboxapi.com/2/files/download' \ 2 | --header 'Accept: application/json' \ 3 | --header 'Dropbox-API-Arg: {"path":"{{ $src }}"}' \ 4 | --header 'Authorization: Bearer {{ $token }}' 5 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mariadb/unlink.blade.php: -------------------------------------------------------------------------------- 1 | sudo mariadb -e "REVOKE ALL PRIVILEGES, GRANT OPTION FROM '{{ $username }}'@'{{ $host }}'" 2>/dev/null || true 2 | 3 | if ! sudo mariadb -e "FLUSH PRIVILEGES"; then 4 | echo 'VITO_SSH_ERROR' && exit 1 5 | fi 6 | 7 | echo "Command executed" 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/postgresql/get-db-list.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo -u postgres psql -c "SELECT 2 | datname AS database_name, 3 | pg_encoding_to_char(encoding) AS charset, 4 | datcollate AS collation 5 | FROM pg_database;"; 6 | then 7 | echo 'VITO_SSH_ERROR' && exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .scribe/ 3 | node_modules/ 4 | public/ 5 | storage/ 6 | vendor/ 7 | composer.lock 8 | .env 9 | .env.example 10 | sail 11 | *.md 12 | *.yml 13 | !*.blade.php 14 | !*.sh 15 | resources/views/ssh/ 16 | resources/views/scribe/ 17 | resources/js/ziggy.js 18 | resources/views/mail/* 19 | -------------------------------------------------------------------------------- /app/Actions/DNSProvider/DeleteDNSProvider.php: -------------------------------------------------------------------------------- 1 | delete(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /public/favicon/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /resources/js/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | 3 | function Skeleton({ className, ...props }: React.ComponentProps<'div'>) { 4 | return
; 5 | } 6 | 7 | export { Skeleton }; 8 | -------------------------------------------------------------------------------- /resources/views/ssh/composer/composer-install.blade.php: -------------------------------------------------------------------------------- 1 | if ! cd {{ $path }}; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! php{{ $phpVersion }} /usr/local/bin/composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /public/api-docs/swagger-ui/index.css: -------------------------------------------------------------------------------- 1 | html { 2 | box-sizing: border-box; 3 | overflow: -moz-scrollbars-vertical; 4 | overflow-y: scroll; 5 | } 6 | 7 | *, 8 | *:before, 9 | *:after { 10 | box-sizing: inherit; 11 | } 12 | 13 | body { 14 | margin: 0; 15 | background: #fafafa; 16 | } 17 | -------------------------------------------------------------------------------- /resources/views/ssh/services/php/change-default-php.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo rm /usr/bin/php; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo ln -s /usr/bin/php{{ $version }} /usr/bin/php; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | echo "Default php is: " 10 | 11 | php -v 12 | -------------------------------------------------------------------------------- /resources/js/types/server-log.d.ts: -------------------------------------------------------------------------------- 1 | export interface ServerLog { 2 | id: number; 3 | server_id: number; 4 | site_id?: number; 5 | type: string; 6 | name: string; 7 | disk: string; 8 | is_remote: boolean; 9 | created_at: string; 10 | updated_at: string; 11 | 12 | [key: string]: unknown; 13 | } 14 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mysql/get-db-list.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mysql -e "SELECT 2 | SCHEMA_NAME AS database_name, 3 | DEFAULT_CHARACTER_SET_NAME AS charset, 4 | DEFAULT_COLLATION_NAME AS collation 5 | FROM information_schema.SCHEMATA;"; 6 | then 7 | echo 'VITO_SSH_ERROR' && exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /resources/js/components/app-logo.tsx: -------------------------------------------------------------------------------- 1 | import AppLogoIcon from './app-logo-icon'; 2 | 3 | export default function AppLogo() { 4 | return ( 5 | <> 6 |
7 | 8 |
9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /resources/js/types/domain.d.ts: -------------------------------------------------------------------------------- 1 | import { DNSProvider } from './dns-provider'; 2 | 3 | export interface Domain { 4 | id: number; 5 | domain: string; 6 | dns_provider_id: number; 7 | dns_provider?: DNSProvider; 8 | metadata: Record; 9 | created_at: string; 10 | updated_at: string; 11 | } 12 | -------------------------------------------------------------------------------- /public/build/assets/heading-CrC3U2Cb.js: -------------------------------------------------------------------------------- 1 | import{j as e}from"./app-8WgsWSPq.js";function r({title:t,description:s}){return e.jsxs("div",{className:"space-y-0.5",children:[e.jsx("h2",{className:"text-xl font-semibold tracking-tight",children:t}),s&&e.jsx("p",{className:"text-muted-foreground text-sm",children:s})]})}export{r as H}; 2 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mysql/delete-user.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mysql -e "DROP USER IF EXISTS '{{ $username }}'@'{{ $host }}'"; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo mysql -e "FLUSH PRIVILEGES"; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | echo "Command executed" 10 | -------------------------------------------------------------------------------- /app/SSH/Storage/AbstractStorage.php: -------------------------------------------------------------------------------- 1 | {children}
; 6 | } 7 | -------------------------------------------------------------------------------- /resources/js/types/project.d.ts: -------------------------------------------------------------------------------- 1 | import { ProjectUser } from '@/types/project-user'; 2 | 3 | export interface Project { 4 | id: number; 5 | name: string; 6 | owner?: ProjectUser; 7 | users: ProjectUser[]; 8 | role: string; 9 | created_at: string; 10 | updated_at: string; 11 | 12 | [key: string]: unknown; 13 | } 14 | -------------------------------------------------------------------------------- /resources/deployment-scripts/laravel.sh: -------------------------------------------------------------------------------- 1 | git pull origin $BRANCH 2 | 3 | composer install --no-interaction --prefer-dist --optimize-autoloader 4 | php artisan migrate --force 5 | 6 | php artisan optimize:clear 7 | php artisan optimize 8 | 9 | npm install 10 | npm run build 11 | 12 | echo "✅ Deployment completed successfully!" 13 | -------------------------------------------------------------------------------- /resources/js/types/server-provider.d.ts: -------------------------------------------------------------------------------- 1 | export interface ServerProvider { 2 | id: number; 3 | user_id: number; 4 | provider: string; 5 | name: string; 6 | global: boolean; 7 | connected: boolean; 8 | project_id?: number; 9 | created_at: string; 10 | updated_at: string; 11 | 12 | [key: string]: unknown; 13 | } 14 | -------------------------------------------------------------------------------- /resources/views/ssh/os/delete-ssh-key.blade.php: -------------------------------------------------------------------------------- 1 | if [ -f ~/.ssh/authorized_keys ]; then 2 | grep -vF '{!! addslashes(trim($key)) !!}' ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.tmp 2>/dev/null || true 3 | if [ -f ~/.ssh/authorized_keys.tmp ]; then 4 | mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keys 5 | fi 6 | fi 7 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mariadb/delete-user.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mariadb -e "DROP USER IF EXISTS '{{ $username }}'@'{{ $host }}'"; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo mariadb -e "FLUSH PRIVILEGES"; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | echo "Command executed" 10 | -------------------------------------------------------------------------------- /tests/Unit/NotificationChannels/TestNotification.php: -------------------------------------------------------------------------------- 1 | activeSsl && $site->force_ssl) 3 | server { 4 | listen 80; 5 | server_name {{ $site->domain }} {{ $site->getAliasesString() }}; 6 | return 301 https://$host$request_uri; 7 | } 8 | @endif 9 | #[/force-ssl] 10 | -------------------------------------------------------------------------------- /public/build/assets/check-H-rc56N8.js: -------------------------------------------------------------------------------- 1 | import{c}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const e=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],t=c("Check",e);export{t as C}; 7 | -------------------------------------------------------------------------------- /resources/js/types/cronjob.d.ts: -------------------------------------------------------------------------------- 1 | export interface CronJob { 2 | id: number; 3 | server_id: number; 4 | site_id: number | null; 5 | command: string; 6 | user: string; 7 | frequency: string; 8 | status: string; 9 | status_color: 'gray' | 'success' | 'info' | 'warning' | 'danger'; 10 | created_at: string; 11 | updated_at: string; 12 | } 13 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mariadb/uninstall.blade.php: -------------------------------------------------------------------------------- 1 | sudo service mariadb stop 2 | 3 | sudo DEBIAN_FRONTEND=noninteractive apt-get remove mariadb-server mariadb-backup -y 4 | 5 | sudo rm -rf /etc/mysql 6 | sudo rm -rf /var/lib/mysql 7 | sudo rm -rf /var/log/mysql 8 | sudo rm -rf /var/run/mysqld 9 | sudo rm -rf /var/run/mysqld/mysqld.sock 10 | -------------------------------------------------------------------------------- /resources/js/components/date-time.tsx: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | 3 | export default function DateTime({ date, format = 'YYYY-MM-DD HH:mm:ss', className }: { date: string; format?: string; className?: string }) { 4 | return ( 5 | 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /resources/js/components/heading-small.tsx: -------------------------------------------------------------------------------- 1 | export default function HeadingSmall({ title, description }: { title: string; description?: string }) { 2 | return ( 3 |
4 |

{title}

5 | {description &&

{description}

} 6 |
7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /resources/svg/email.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | -------------------------------------------------------------------------------- /app/SiteFeatures/Action.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | public function upload(string $src, string $dest): array; 11 | 12 | public function download(string $src, string $dest): void; 13 | 14 | public function delete(string $src): void; 15 | } 16 | -------------------------------------------------------------------------------- /app/ServerFeatures/Action.php: -------------------------------------------------------------------------------- 1 | 4 |

{title}

5 | {description &&

{description}

} 6 | 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /resources/js/stores/useInputFocus.ts: -------------------------------------------------------------------------------- 1 | // stores/useInputFocus.ts 2 | import { create } from 'zustand'; 3 | 4 | type InputFocusStore = { 5 | isFocused: boolean; 6 | setFocused: (value: boolean) => void; 7 | }; 8 | 9 | export const useInputFocus = create((set) => ({ 10 | isFocused: false, 11 | setFocused: (value) => set({ isFocused: value }), 12 | })); 13 | -------------------------------------------------------------------------------- /resources/js/types/redirect.d.ts: -------------------------------------------------------------------------------- 1 | export interface Redirect { 2 | id: number; 3 | server_id: number; 4 | site_id: number; 5 | from: string; 6 | to: string; 7 | mode: string; 8 | status: string; 9 | status_color: 'gray' | 'success' | 'info' | 'warning' | 'danger'; 10 | created_at: string; 11 | updated_at: string; 12 | 13 | [key: string]: unknown; 14 | } 15 | -------------------------------------------------------------------------------- /resources/views/ssh/services/monitoring/vito-agent/uninstall.blade.php: -------------------------------------------------------------------------------- 1 | sudo service vito-agent stop 2 | 3 | sudo systemctl disable vito-agent 4 | 5 | sudo rm -f /usr/local/bin/vito-agent 6 | 7 | sudo rm -f /etc/systemd/system/vito-agent.service 8 | 9 | sudo rm -rf /etc/vito-agent 10 | 11 | sudo systemctl daemon-reload 12 | 13 | echo "Vito Agent uninstalled successfully" 14 | -------------------------------------------------------------------------------- /resources/views/ssh/storage/dropbox/upload.blade.php: -------------------------------------------------------------------------------- 1 | curl -sb --location --request POST 'https://content.dropboxapi.com/2/files/upload' \ 2 | --header 'Accept: application/json' \ 3 | --header 'Dropbox-API-Arg: {"path":"{{ $dest }}"}' \ 4 | --header 'Content-Type: text/plain; charset=dropbox-cors-hack' \ 5 | --header 'Authorization: Bearer {{ $token }}' \ 6 | --data-binary '@{{ $src }}' 7 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | id)->delete(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/StorageProviders/AbstractStorageProvider.php: -------------------------------------------------------------------------------- 1 | ; 14 | } 15 | -------------------------------------------------------------------------------- /resources/views/ssh/services/firewall/ufw/backup-rules.blade.php: -------------------------------------------------------------------------------- 1 | sudo cp /etc/ufw/before.rules /tmp/ufw.before.backup 2 | sudo cp /etc/ufw/after.rules /tmp/ufw.after.backup 3 | sudo cp /etc/ufw/user.rules /tmp/ufw.user.backup 4 | sudo cp /etc/ufw/before6.rules /tmp/ufw.before6.backup 5 | sudo cp /etc/ufw/after6.rules /tmp/ufw.after6.backup 6 | sudo cp /etc/ufw/user6.rules /tmp/ufw.user6.backup 7 | -------------------------------------------------------------------------------- /public/build/assets/cloud-2IT3iR1-.js: -------------------------------------------------------------------------------- 1 | import{c as o}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const c=[["path",{d:"M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z",key:"p7xjir"}]],e=o("Cloud",c);export{e as C}; 7 | -------------------------------------------------------------------------------- /public/build/assets/text-link-BdVdM4qt.js: -------------------------------------------------------------------------------- 1 | import{j as t,Y as n}from"./app-8WgsWSPq.js";import{c as a}from"./utils-DDOqEnVW.js";function u({className:r="",children:e,...o}){return t.jsx(n,{className:a("text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-neutral-500",r),...o,children:e})}export{u as T}; 2 | -------------------------------------------------------------------------------- /resources/js/types/deployment-script.d.ts: -------------------------------------------------------------------------------- 1 | export interface DeploymentScriptConfigs { 2 | restart_workers: boolean; 3 | } 4 | 5 | export interface DeploymentScript { 6 | id: number; 7 | site_id: number; 8 | name: string; 9 | content: string; 10 | configs: DeploymentScriptConfigs; 11 | created_at: string; 12 | updated_at: string; 13 | 14 | [key: string]: unknown; 15 | } 16 | -------------------------------------------------------------------------------- /app/SiteFeatures/ActionInterface.php: -------------------------------------------------------------------------------- 1 | is_active = false; 12 | $ssl->save(); 13 | $ssl->site->webserver()->updateVHost($ssl->site, regenerate: [ 14 | 'port', 15 | ]); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/ServerFeatures/ActionInterface.php: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/ServerFeatures/FeatureInterface.php: -------------------------------------------------------------------------------- 1 | 'phpmyadmin', 11 | 'php_version' => 'PHP version, example: 8.1, 8.2', 12 | ]); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/svg/force-ssl-disabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /resources/svg/memory.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/postgresql/restore.blade.php: -------------------------------------------------------------------------------- 1 | if ! DEBIAN_FRONTEND=noninteractive unzip {{ $file }}.zip; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo -u postgres psql -d {{ $database }} -f {{ $file }}.sql; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! rm {{ $file }}.sql {{ $file }}.zip; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /public/build/assets/chevrons-up-down-C_9lshW_.js: -------------------------------------------------------------------------------- 1 | import{c as o}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const e=[["path",{d:"m7 15 5 5 5-5",key:"1hf1tw"}],["path",{d:"m7 9 5-5 5 5",key:"sgt6xg"}]],n=o("ChevronsUpDown",e);export{n as C}; 7 | -------------------------------------------------------------------------------- /public/build/assets/circle-check-C5ooGkJD.js: -------------------------------------------------------------------------------- 1 | import{c}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],r=c("CircleCheck",e);export{r as C}; 7 | -------------------------------------------------------------------------------- /resources/js/types/firewall.d.ts: -------------------------------------------------------------------------------- 1 | export interface FirewallRule { 2 | id: number; 3 | name: string; 4 | server_id: number; 5 | type: string; 6 | protocol: string; 7 | port: number; 8 | source: string; 9 | mask: number; 10 | note: string; 11 | status: string; 12 | status_color: 'gray' | 'success' | 'info' | 'warning' | 'danger'; 13 | created_at: string; 14 | updated_at: string; 15 | } 16 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mysql/get-users-list.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mysql -e "SELECT u.User, 2 | u.Host, 3 | (SELECT group_concat(distinct p.TABLE_SCHEMA) 4 | FROM information_schema.SCHEMA_PRIVILEGES p 5 | WHERE p.GRANTEE = concat('\'', u.User, '\'', '@', '\'', u.Host, '\'')) as Privileges 6 | FROM mysql.user u;"; 7 | then 8 | echo 'VITO_SSH_ERROR' && exit 1 9 | fi 10 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/vhost.blade.php: -------------------------------------------------------------------------------- 1 | #[header] 2 | @foreach($header ?? [] as $header) 3 | {{ $header }} 4 | @endforeach 5 | #[/header] 6 | 7 | server { 8 | #[main] 9 | @foreach($main ?? [] as $main) 10 | {{ $main }} 11 | @endforeach 12 | #[/main] 13 | } 14 | 15 | #[footer] 16 | @foreach($footer ?? [] as $footer) 17 | {{ $footer }} 18 | @endforeach 19 | #[/footer] 20 | -------------------------------------------------------------------------------- /.env.sail: -------------------------------------------------------------------------------- 1 | APP_NAME=Vito 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL= 6 | APP_PORT=8000 7 | APP_SERVICE=app 8 | 9 | FILESYSTEM_DRIVER=local 10 | 11 | MAIL_MAILER=smtp 12 | MAIL_HOST= 13 | MAIL_PORT= 14 | MAIL_USERNAME=null 15 | MAIL_PASSWORD=null 16 | MAIL_ENCRYPTION=null 17 | MAIL_FROM_ADDRESS="noreply@${APP_NAME}" 18 | MAIL_FROM_NAME="${APP_NAME}" 19 | 20 | REDIS_HOST=redis 21 | REDIS_PORT=6379 22 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mariadb/get-users-list.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mariadb -e "SELECT u.User, 2 | u.Host, 3 | (SELECT group_concat(distinct p.TABLE_SCHEMA) 4 | FROM information_schema.SCHEMA_PRIVILEGES p 5 | WHERE p.GRANTEE = concat('\'', u.User, '\'', '@', '\'', u.Host, '\'')) as Privileges 6 | FROM mysql.user u;"; 7 | then 8 | echo 'VITO_SSH_ERROR' && exit 1 9 | fi 10 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/caddy/uninstall-caddy.blade.php: -------------------------------------------------------------------------------- 1 | sudo service caddy stop 2 | 3 | sudo DEBIAN_FRONTEND=noninteractive sudo apt remove caddy -y 4 | 5 | sudo rm -rf /etc/caddy 6 | sudo rm -rf /var/log/caddy 7 | sudo rm -rf /var/lib/caddy 8 | sudo rm -rf /var/cache/caddy 9 | sudo rm -rf /usr/share/caddy 10 | sudo rm -rf /etc/systemd/system/caddy.service 11 | 12 | sudo systemctl daemon-reload 13 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/vhost-blocks/port.blade.php: -------------------------------------------------------------------------------- 1 | #[port] 2 | @if (!$site->activeSsl || !$site->force_ssl) 3 | listen 80; 4 | listen [::]:80; 5 | @endif 6 | @if ($site->activeSsl) 7 | listen 443 ssl; 8 | listen [::]:443 ssl; 9 | ssl_certificate {{ $site->activeSsl->certificate_path }}; 10 | ssl_certificate_key {{ $site->activeSsl->pk_path }}; 11 | @endif 12 | #[/port] 13 | -------------------------------------------------------------------------------- /app/Enums/PHPIniType.php: -------------------------------------------------------------------------------- 1 | value; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /public/build/assets/index-BIIQn21O.js: -------------------------------------------------------------------------------- 1 | import{r as i,j as t}from"./app-8WgsWSPq.js";import{P as o}from"./index-DUU4w66S.js";var s=Object.freeze({position:"absolute",border:0,width:1,height:1,padding:0,margin:-1,overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",wordWrap:"normal"}),d="VisuallyHidden",e=i.forwardRef((r,a)=>t.jsx(o.span,{...r,ref:a,style:{...s,...r.style}}));e.displayName=d;var p=e;export{p as R,s as V}; 2 | -------------------------------------------------------------------------------- /resources/js/types/script.d.ts: -------------------------------------------------------------------------------- 1 | import { ScriptExecution } from './script-execution'; 2 | import { User } from './user'; 3 | 4 | export interface Script { 5 | id: number; 6 | user_id: number; 7 | user?: User; 8 | name: string; 9 | content: string; 10 | variables: string[]; 11 | last_execution?: ScriptExecution; 12 | created_at: string; 13 | updated_at: string; 14 | 15 | [key: string]: unknown; 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Middleware/MustBeAdminMiddleware.php: -------------------------------------------------------------------------------- 1 | user()?->isAdmin()) { 13 | abort(404); 14 | } 15 | 16 | return $next($request); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mysql/backup.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo DEBIAN_FRONTEND=noninteractive mysqldump -u root {{ $database }} > {{ $file }}.sql; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! DEBIAN_FRONTEND=noninteractive zip {{ $file }}.zip {{ $file }}.sql; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! rm {{ $file }}.sql; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mysql/restore.blade.php: -------------------------------------------------------------------------------- 1 | if ! DEBIAN_FRONTEND=noninteractive unzip {{ $file }}.zip; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo DEBIAN_FRONTEND=noninteractive mysql -u root {{ $database }} < {{ $file }}.sql; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! rm {{ $file }}.sql {{ $file }}.zip; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /app/Actions/Server/Update.php: -------------------------------------------------------------------------------- 1 | status = ServerStatus::UPDATING; 14 | $server->save(); 15 | dispatch(new UpdateJob($server))->onQueue('ssh'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /docker/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | user=root 4 | logfile=/var/log/supervisor/supervisord.log 5 | pidfile=/var/run/supervisord.pid 6 | redirect_stderr=true 7 | 8 | [program:worker] 9 | user=root 10 | autostart=1 11 | autorestart=1 12 | numprocs=1 13 | command=/usr/bin/php /var/www/html/artisan horizon 14 | redirect_stderr=true 15 | stdout_logfile=/var/www/html/storage/logs/worker.log 16 | stopwaitsecs=3600 17 | -------------------------------------------------------------------------------- /public/build/assets/export-DVXz8Gr6.js: -------------------------------------------------------------------------------- 1 | import{j as o}from"./app-8WgsWSPq.js";import{B as r}from"./button-Cfqokzhp.js";import{D as i}from"./download-DRyR4IfQ.js";/* empty css */import"./utils-DDOqEnVW.js";import"./index-CN-FHsb7.js";import"./createLucideIcon-COM2DoSP.js";function u(){const t=()=>{window.open(route("vito-settings.export"),"_blank")};return o.jsxs(r,{onClick:t,children:[o.jsx(i,{}),"Export"]})}export{u as default}; 2 | -------------------------------------------------------------------------------- /public/build/assets/lock-C91yC-Vq.js: -------------------------------------------------------------------------------- 1 | import{c}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const e=[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]],t=c("Lock",e);export{t as L}; 7 | -------------------------------------------------------------------------------- /resources/js/types/worker.d.ts: -------------------------------------------------------------------------------- 1 | export interface Worker { 2 | id: number; 3 | server_id: number; 4 | site_id: number | null; 5 | name: string; 6 | command: string; 7 | user: string; 8 | auto_start: boolean; 9 | auto_restart: boolean; 10 | numprocs: number; 11 | status: string; 12 | status_color: 'gray' | 'success' | 'info' | 'warning' | 'danger'; 13 | created_at: string; 14 | updated_at: string; 15 | } 16 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mariadb/backup.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo DEBIAN_FRONTEND=noninteractive mysqldump -u root {{ $database }} > {{ $file }}.sql; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! DEBIAN_FRONTEND=noninteractive zip {{ $file }}.zip {{ $file }}.sql; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! rm {{ $file }}.sql; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mariadb/restore.blade.php: -------------------------------------------------------------------------------- 1 | if ! DEBIAN_FRONTEND=noninteractive unzip {{ $file }}.zip; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo DEBIAN_FRONTEND=noninteractive mariadb -u root {{ $database }} < {{ $file }}.sql; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! rm {{ $file }}.sql {{ $file }}.zip; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /app/Enums/BackupType.php: -------------------------------------------------------------------------------- 1 | value; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Facades/Notifier.php: -------------------------------------------------------------------------------- 1 | { 6 | window.open(route('vito-settings.export'), '_blank'); 7 | }; 8 | 9 | return ( 10 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/uninstall-nginx.blade.php: -------------------------------------------------------------------------------- 1 | sudo service nginx stop 2 | 3 | sudo DEBIAN_FRONTEND=noninteractive apt-get purge nginx nginx-common nginx-full -y 4 | 5 | sudo rm -rf /etc/nginx 6 | sudo rm -rf /var/log/nginx 7 | sudo rm -rf /var/lib/nginx 8 | sudo rm -rf /var/cache/nginx 9 | sudo rm -rf /usr/share/nginx 10 | sudo rm -rf /etc/systemd/system/nginx.service 11 | 12 | sudo systemctl daemon-reload 13 | -------------------------------------------------------------------------------- /app/WorkflowActions/Site/CreateLoadBalancerSite.php: -------------------------------------------------------------------------------- 1 | 'load-balancer', 11 | 'method' => 'Load balancing method in (round-robin/least-connections/ip-hash)', 12 | ]); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/js/components/ui/input-error.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | import { type HTMLAttributes } from 'react'; 3 | 4 | export default function InputError({ message, className = '', ...props }: HTMLAttributes & { message?: string }) { 5 | return message ? ( 6 |

7 | {message} 8 |

9 | ) : null; 10 | } 11 | -------------------------------------------------------------------------------- /resources/views/emails/project-invitation.blade.php: -------------------------------------------------------------------------------- 1 | @component('mail::message') 2 | {{ __('You have been invited to join the :project project!', ['project' => $project->name]) }} 3 | 4 | @component('mail::button', ['url' => $acceptUrl]) 5 | {{ __('Accept Invitation') }} 6 | @endcomponent 7 | 8 | {{ __('If you did not expect to receive an invitation to this project, you may discard this email.') }} 9 | @endcomponent 10 | -------------------------------------------------------------------------------- /resources/js/components/form-successful.tsx: -------------------------------------------------------------------------------- 1 | import { CheckIcon } from 'lucide-react'; 2 | import { Transition } from '@headlessui/react'; 3 | 4 | export default function FormSuccessful({ successful }: { successful: boolean }) { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/caddy/create-custom-ssl.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mkdir -p {{ $path }}; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! echo "{{ $certificate }}" | sudo tee {{ $certificatePath }}; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! echo "{{ $pk }}" | sudo tee {{ $pkPath }}; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | 13 | echo "Successfully received certificate" 14 | -------------------------------------------------------------------------------- /app/Enums/UserRole.php: -------------------------------------------------------------------------------- 1 | value; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /public/build/assets/ellipsis-CV-QbUhm.js: -------------------------------------------------------------------------------- 1 | import{c}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const i=[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]],r=c("Ellipsis",i);export{r as E}; 7 | -------------------------------------------------------------------------------- /app/Actions/SSL/ActivateSSL.php: -------------------------------------------------------------------------------- 1 | site->ssls()->update(['is_active' => false]); 12 | $ssl->is_active = true; 13 | $ssl->save(); 14 | $ssl->site->webserver()->updateVHost($ssl->site, regenerate: [ 15 | 'port', 16 | ]); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /public/vendor/log-viewer/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/app.js": "/app.js?id=b5eb6497b80ecd00237a857b35fcc1d6", 3 | "/app.css": "/app.css?id=bf9e77abce3da8caacd004d57e4e8429", 4 | "/img/log-viewer-128.png": "/img/log-viewer-128.png?id=d576c6d2e16074d3f064e60fe4f35166", 5 | "/img/log-viewer-32.png": "/img/log-viewer-32.png?id=f8ec67d10f996aa8baf00df3b61eea6d", 6 | "/img/log-viewer-64.png": "/img/log-viewer-64.png?id=8902d596fc883ca9eb8105bb683568c6" 7 | } 8 | -------------------------------------------------------------------------------- /resources/js/components/icon.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | import { type LucideProps } from 'lucide-react'; 3 | import { type ComponentType } from 'react'; 4 | 5 | interface IconProps extends Omit { 6 | iconNode: ComponentType; 7 | } 8 | 9 | export function Icon({ iconNode: IconComponent, className, ...props }: IconProps) { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /resources/js/types/ssl.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerLog } from '@/types/server-log'; 2 | 3 | export interface SSL { 4 | id: number; 5 | server_id: number; 6 | site_id: number; 7 | is_active: boolean; 8 | type: string; 9 | log?: ServerLog; 10 | status: string; 11 | status_color: 'gray' | 'success' | 'info' | 'warning' | 'danger'; 12 | expires_at: string; 13 | created_at: string; 14 | updated_at: string; 15 | 16 | [key: string]: unknown; 17 | } 18 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | ij_any_block_comment_at_first_column = false 11 | 12 | [{*.php,composer.json,composer.lock}] 13 | indent_size = 4 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | 18 | [*.{yml,yaml}] 19 | indent_size = 2 20 | 21 | [docker-compose.yml] 22 | indent_size = 4 23 | -------------------------------------------------------------------------------- /public/build/assets/globe-BgYtBYj_.js: -------------------------------------------------------------------------------- 1 | import{c}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]],a=c("Globe",e);export{a as G}; 7 | -------------------------------------------------------------------------------- /resources/svg/book-open.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | -------------------------------------------------------------------------------- /resources/views/ssh/services/firewall/ufw/restore-rules.blade.php: -------------------------------------------------------------------------------- 1 | sudo ufw --force disable 2 | 3 | sudo cp /tmp/ufw.before.backup /etc/ufw/before.rules 4 | sudo cp /tmp/ufw.after.backup /etc/ufw/after.rules 5 | sudo cp /tmp/ufw.user.backup /etc/ufw/user.rules 6 | sudo cp /tmp/ufw.before6.backup /etc/ufw/before6.rules 7 | sudo cp /tmp/ufw.after6.backup /etc/ufw/after6.rules 8 | sudo cp /tmp/ufw.user6.backup /etc/ufw/user6.rules 9 | 10 | sudo ufw --force enable 11 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/caddy/vhost-blocks/php.blade.php: -------------------------------------------------------------------------------- 1 | #[php] 2 | root * {{ $site->getWebDirectoryPath() }} 3 | @php 4 | $phpSocket = "unix//var/run/php/php{$site->php_version}-fpm.sock"; 5 | if ($site->isIsolated()) { 6 | $phpSocket = "unix//run/php/php{$site->php_version}-fpm-{$site->user}.sock"; 7 | } 8 | @endphp 9 | try_files {path} {path}/ /index.php?{query} 10 | php_fastcgi {{ $phpSocket }} 11 | file_server 12 | #[/php] 13 | -------------------------------------------------------------------------------- /public/build/assets/ellipsis-vertical-CyajjklM.js: -------------------------------------------------------------------------------- 1 | import{c}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const e=[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"12",cy:"5",r:"1",key:"gxeob9"}],["circle",{cx:"12",cy:"19",r:"1",key:"lyex9k"}]],r=c("EllipsisVertical",e);export{r as E}; 7 | -------------------------------------------------------------------------------- /public/build/assets/trash-CU_5rEP3.js: -------------------------------------------------------------------------------- 1 | import{c}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const a=[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}]],t=c("Trash",a);export{t as T}; 7 | -------------------------------------------------------------------------------- /resources/js/types/command-execution.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerLog } from '@/types/server-log'; 2 | 3 | export interface CommandExecution { 4 | id: number; 5 | command_id: number; 6 | server_id: number; 7 | user_id: number; 8 | server_log_id: number; 9 | log: ServerLog; 10 | status: string; 11 | status_color: 'gray' | 'success' | 'info' | 'warning' | 'danger'; 12 | created_at: string; 13 | updated_at: string; 14 | 15 | [key: string]: unknown; 16 | } 17 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/create-custom-ssl.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo mkdir -p {{ $path }}; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! echo "{{ $certificate }}" | sudo tee {{ $certificatePath }} > /dev/null; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! echo "{{ $pk }}" | sudo tee {{ $pkPath }} > /dev/null; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | 13 | echo "Successfully received certificate" 14 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/vhost-blocks/core.blade.php: -------------------------------------------------------------------------------- 1 | #[core] 2 | server_name {{ $site->domain }} {{ $site->getAliasesString() }}; 3 | root {{ $site->getWebDirectoryPath() }}; 4 | add_header X-Frame-Options "SAMEORIGIN"; 5 | add_header X-Content-Type-Options "nosniff"; 6 | charset utf-8; 7 | access_log off; 8 | error_log /var/log/nginx/{{ $site->domain }}-error.log error; 9 | location ~ /\.(?!well-known).* { 10 | deny all; 11 | } 12 | #[/core] 13 | -------------------------------------------------------------------------------- /app/Plugins/Interfaces/PluginInterface.php: -------------------------------------------------------------------------------- 1 | 3 | 5 | -------------------------------------------------------------------------------- /app/WorkflowActions/Site/CreatePHPBlankSite.php: -------------------------------------------------------------------------------- 1 | 'php-blank', 11 | 'php_version' => 'PHP version, example: 8.1, 8.2', 12 | 'web_directory' => 'Web directory, example: public (optional)', 13 | ]); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /public/build/assets/eye-NVKf5C3O.js: -------------------------------------------------------------------------------- 1 | import{c}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const e=[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],r=c("Eye",e);export{r as E}; 7 | -------------------------------------------------------------------------------- /resources/views/ssh/os/install-dependencies.blade.php: -------------------------------------------------------------------------------- 1 | sudo DEBIAN_FRONTEND=noninteractive apt-get install -y software-properties-common curl zip unzip git gcc openssl ufw cron 2 | git config --global user.email "{{ $email }}" 3 | git config --global user.name "{{ $name }}" 4 | 5 | # Install Node.js 6 | curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - 7 | sudo DEBIAN_FRONTEND=noninteractive apt-get update 8 | sudo DEBIAN_FRONTEND=noninteractive apt-get install nodejs -y 9 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/postgresql/get-charsets.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo -u postgres psql -c "SELECT collname as collation, 2 | pg_encoding_to_char(collencoding) as charset, 3 | '' as id, 4 | '' as \"default\", 5 | 'Yes' as compiled, 6 | '' as sortlen, 7 | '' as pad_attribute 8 | FROM pg_collation 9 | WHERE not pg_encoding_to_char(collencoding) = '' 10 | ORDER BY charset;"; 11 | then 12 | echo 'VITO_SSH_ERROR' && exit 1 13 | fi 14 | -------------------------------------------------------------------------------- /resources/js/types/backup-file.d.ts: -------------------------------------------------------------------------------- 1 | import { Backup } from '@/types/backup'; 2 | 3 | export interface BackupFile { 4 | id: number; 5 | backup_id: number; 6 | backup: Backup; 7 | server_id: number; 8 | name: string; 9 | size: number; 10 | restored_to: string; 11 | restored_at: string; 12 | status: string; 13 | status_color: 'gray' | 'success' | 'info' | 'warning' | 'danger'; 14 | created_at: string; 15 | updated_at: string; 16 | [key: string]: unknown; 17 | } 18 | -------------------------------------------------------------------------------- /resources/svg/hetzner.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /resources/js/types/metric.d.ts: -------------------------------------------------------------------------------- 1 | export interface Metric { 2 | date: string; 3 | load: number; 4 | memory_total: number; 5 | memory_used: number; 6 | memory_free: number; 7 | disk_total: number; 8 | disk_used: number; 9 | disk_free: number; 10 | date_interval: string; 11 | 12 | [key: string]: number | string; 13 | } 14 | 15 | export interface MetricsFilter { 16 | period: string; 17 | from?: string; 18 | to?: string; 19 | [key: string]: number | string; 20 | } 21 | -------------------------------------------------------------------------------- /resources/views/ssh/services/process-manager/supervisor/worker.blade.php: -------------------------------------------------------------------------------- 1 | [program:{{ $name }}] 2 | process_name=%(program_name)s_%(process_num)02d 3 | @if (!is_null($directory)) 4 | directory={{ $directory }} 5 | @endif 6 | command={{ $command }} 7 | autostart={{ $autoStart }} 8 | autorestart={{ $autoRestart }} 9 | user={{ $user }} 10 | numprocs={{ $numprocs }} 11 | redirect_stderr=true 12 | stdout_logfile={{ $logFile }} 13 | stopwaitsecs=3600 14 | stopasgroup=true 15 | killasgroup=true 16 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/vhost-blocks/reverse-proxy.blade.php: -------------------------------------------------------------------------------- 1 | #[reverse-proxy] 2 | add_header X-Frame-Options DENY; 3 | add_header X-Content-Type-Options nosniff; 4 | location / { 5 | proxy_pass http://localhost:{{ $site->port }}; 6 | proxy_http_version 1.1; 7 | proxy_set_header Upgrade $http_upgrade; 8 | proxy_set_header Connection 'upgrade'; 9 | proxy_set_header Host $host; 10 | proxy_cache_bypass $http_upgrade; 11 | } 12 | #[/reverse-proxy] 13 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /database/seeders/UsersSeeder.php: -------------------------------------------------------------------------------- 1 | create([ 14 | 'name' => 'Demo User', 15 | 'email' => 'demo@vitodeploy.com', 16 | ]); 17 | 18 | $user->ensureHasDefaultProject(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /public/build/assets/download-DRyR4IfQ.js: -------------------------------------------------------------------------------- 1 | import{c as o}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const e=[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]],a=o("Download",e);export{a as D}; 7 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 18 | 19 | return $app; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts(): array 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /public/build/assets/triangle-alert-cIqJ3BmP.js: -------------------------------------------------------------------------------- 1 | import{c as e}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const a=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],o=e("TriangleAlert",a);export{o as T}; 7 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/postgresql/get-users-list.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo -u postgres psql -c "SELECT r.rolname AS username, 2 | '' as host, 3 | STRING_AGG(d.datname, ',') AS databases 4 | FROM pg_roles r 5 | JOIN 6 | pg_database d ON has_database_privilege(r.rolname, d.datname, 'CONNECT') 7 | WHERE r.rolcanlogin 8 | GROUP BY r.rolname 9 | ORDER BY r.rolname;"; 10 | then 11 | echo 'VITO_SSH_ERROR' && exit 1 12 | fi 13 | -------------------------------------------------------------------------------- /resources/svg/monitoring.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | -------------------------------------------------------------------------------- /resources/svg/vitomonitor.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | -------------------------------------------------------------------------------- /tests/Feature/VitoSettingsTest.php: -------------------------------------------------------------------------------- 1 | actingAs($this->user); 15 | 16 | $this->get(route('vito-settings.export')) 17 | ->assertDownload('vito-backup-'.date('Y-m-d').'.zip'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Exceptions/FailedToDeployGitHook.php: -------------------------------------------------------------------------------- 1 | header('X-Inertia')) { 14 | return back()->with('error', 'Failed to deploy git hook.'); 15 | } 16 | 17 | return null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Http/Controllers/HomeController.php: -------------------------------------------------------------------------------- 1 | check()) { 14 | return redirect()->route('servers'); 15 | } 16 | 17 | return redirect()->route('login'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson() ? null : url('/'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "style": "default", 3 | "rsc": false, 4 | "tsx": true, 5 | "tailwind": { 6 | "css": "resources/css/app.css", 7 | "baseColor": "neutral", 8 | "cssVariables": true, 9 | "prefix": "" 10 | }, 11 | "aliases": { 12 | "components": "@/components", 13 | "utils": "@/lib/utils", 14 | "ui": "@/components/ui", 15 | "lib": "@/lib", 16 | "hooks": "@/hooks" 17 | }, 18 | "iconLibrary": "lucide" 19 | } 20 | -------------------------------------------------------------------------------- /resources/views/ssh/services/php/update-php-settings.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo sed -i 's,^{{ $variable }} =.*$,{{ $variable }} = {{ $value }},' /etc/php/{{ $version }}/cli/php.ini; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo sed -i 's,^{{ $variable }} =.*$,{{ $variable }} = {{ $value }},' /etc/php/{{ $version }}/fpm/php.ini; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! sudo service php{{ $version }}-fpm restart; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /app/Exceptions/FailedToDestroyGitHook.php: -------------------------------------------------------------------------------- 1 | header('X-Inertia')) { 14 | return back()->with('error', 'Failed to destroy git hook.'); 15 | } 16 | 17 | return null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /resources/views/ssh/os/resource-info.blade.php: -------------------------------------------------------------------------------- 1 | echo "load:$(uptime | awk -F'load average:' '{print $2}' | awk -F, '{print $1}' | tr -d ' ')" 2 | echo "memory_total:$(free -k | awk 'NR==2{print $2}')" 3 | echo "memory_used:$(free -k | awk 'NR==2{print $3}')" 4 | echo "memory_free:$(free -k | awk 'NR==2{print $7}')" 5 | echo "disk_total:$(df -BM / | awk 'NR==2{print $2}' | sed 's/M//')" 6 | echo "disk_used:$(df -BM / | awk 'NR==2{print $3}' | sed 's/M//')" 7 | echo "disk_free:$(df -BM / | awk 'NR==2{print $4}' | sed 's/M//')" 8 | -------------------------------------------------------------------------------- /app/Actions/Redirect/DeleteRedirect.php: -------------------------------------------------------------------------------- 1 | status = RedirectStatus::DELETING; 15 | $redirect->save(); 16 | 17 | dispatch(new DeleteJob($site, $redirect))->onQueue('ssh'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/DTOs/GitHub/AuthorDto.php: -------------------------------------------------------------------------------- 1 | log; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /database/migrations/2023_07_21_210213_update_firewall_rules_table.php: -------------------------------------------------------------------------------- 1 | installPlugin->handle($plugin->repo, $plugin); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Notifications/NotificationInterface.php: -------------------------------------------------------------------------------- 1 | > /root/.ssh/authorized_keys", 3 | "servers.create.public_key_warning": "Your server needs to have a new unused installation of supported operating systems and must have a root user. To get started, add our public key to /root/.ssh/authorized_keys file by running the bellow command on your server as root.", 4 | "server_providers.plan": ":name - :cpu Cores - :memory Memory - :disk Disk" 5 | } 6 | -------------------------------------------------------------------------------- /resources/js/icons/vito.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { LucideProps } from 'lucide-react'; 3 | import AppLogoIcon from '@/components/app-logo-icon'; 4 | import { cn } from '@/lib/utils'; 5 | 6 | export const VitoIcon = React.forwardRef(({ color = 'currentColor', strokeWidth = 30, className, ...rest }, ref) => { 7 | return ; 8 | }); 9 | 10 | export default VitoIcon; 11 | -------------------------------------------------------------------------------- /app/Exceptions/SourceControlIsNotConnected.php: -------------------------------------------------------------------------------- 1 | header('X-Inertia')) { 14 | return back()->with('error', 'Source control is not connected.'); 15 | } 16 | 17 | return null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /resources/svg/custom.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | -------------------------------------------------------------------------------- /resources/svg/server.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | -------------------------------------------------------------------------------- /public/build/assets/users-CWbfDbF5.js: -------------------------------------------------------------------------------- 1 | import{c as e}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const c=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["path",{d:"M16 3.13a4 4 0 0 1 0 7.75",key:"1da9ce"}]],s=e("Users",c);export{s as U}; 7 | -------------------------------------------------------------------------------- /resources/js/types/dynamic-field-config.d.ts: -------------------------------------------------------------------------------- 1 | export interface DynamicFieldConfig { 2 | type: 'text' | 'textarea' | 'select' | 'checkbox' | 'component' | 'alert'; 3 | name: string; 4 | options?: string[] | { [key: string]: string }; 5 | component?: string; 6 | placeholder?: string; 7 | description?: string; 8 | label?: string; 9 | default?: string | number | boolean; 10 | link?: { 11 | label: string; 12 | url: string; 13 | }; 14 | className?: string; 15 | componentProps?: Record; 16 | } 17 | -------------------------------------------------------------------------------- /resources/views/ssh/services/php/uninstall-php.blade.php: -------------------------------------------------------------------------------- 1 | sudo service php{{ $version }}-fpm stop 2 | 3 | if ! sudo DEBIAN_FRONTEND=noninteractive apt-get remove -y php{{ $version }} php{{ $version }}-fpm php{{ $version }}-mbstring php{{ $version }}-mysql php{{ $version }}-mcrypt php{{ $version }}-gd php{{ $version }}-xml php{{ $version }}-curl php{{ $version }}-gettext php{{ $version }}-zip php{{ $version }}-bcmath php{{ $version }}-soap php{{ $version }}-redis php{{ $version }}-sqlite3; then 4 | echo 'VITO_SSH_ERROR' && exit 1 5 | fi 6 | -------------------------------------------------------------------------------- /app/ValidationRules/RestrictedIPAddressesRule.php: -------------------------------------------------------------------------------- 1 | translate(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /resources/js/lib/site-helper.ts: -------------------------------------------------------------------------------- 1 | import { Site } from '@/types/site'; 2 | 3 | const siteHelper = { 4 | getStoredSite() { 5 | const storedSite = localStorage.getItem('site'); 6 | if (storedSite) { 7 | return JSON.parse(storedSite) as Site; 8 | } 9 | return null; 10 | }, 11 | storeSite(site?: Site) { 12 | if (!site) { 13 | localStorage.removeItem('site'); 14 | return; 15 | } 16 | localStorage.setItem('site', JSON.stringify(site)); 17 | }, 18 | }; 19 | 20 | export default siteHelper; 21 | -------------------------------------------------------------------------------- /resources/js/hooks/use-initials.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react'; 2 | 3 | export function useInitials() { 4 | return useCallback((fullName: string): string => { 5 | const names = fullName.trim().split(' '); 6 | 7 | if (names.length === 0) return ''; 8 | if (names.length === 1) return names[0].charAt(0).toUpperCase(); 9 | 10 | const firstInitial = names[0].charAt(0); 11 | const lastInitial = names[names.length - 1].charAt(0); 12 | 13 | return `${firstInitial}${lastInitial}`.toUpperCase(); 14 | }, []); 15 | } 16 | -------------------------------------------------------------------------------- /resources/js/lib/event-bus.tsx: -------------------------------------------------------------------------------- 1 | type Callback = (data: unknown) => void; 2 | 3 | const events: Record = {}; 4 | 5 | export const EventBus = { 6 | on(event: string, callback: Callback) { 7 | if (!events[event]) events[event] = []; 8 | events[event].push(callback); 9 | }, 10 | off(event: string, callback: Callback) { 11 | events[event] = events[event]?.filter((cb) => cb !== callback) || []; 12 | }, 13 | emit(event: string, data?: unknown) { 14 | events[event]?.forEach((cb) => cb(data)); 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /app/Http/Controllers/API/HealthController.php: -------------------------------------------------------------------------------- 1 | json([ 15 | 'success' => true, 16 | 'version' => config('app.version'), 17 | ]); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/build/assets/refresh-cw-v4O_-xG6.js: -------------------------------------------------------------------------------- 1 | import{c as e}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const t=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],c=e("RefreshCw",t);export{c as R}; 7 | -------------------------------------------------------------------------------- /app/Facades/Plugins.php: -------------------------------------------------------------------------------- 1 | 11 | V 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /app/WorkflowActions/WorkflowActionInterface.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class ServerLogFactory extends Factory 12 | { 13 | protected $model = ServerLog::class; 14 | 15 | public function definition(): array 16 | { 17 | return [ 18 | 'type' => 'test-log', 19 | 'name' => 'test.log', 20 | 'disk' => 'server-logs', 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /database/factories/SshKeyFactory.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class SshKeyFactory extends Factory 12 | { 13 | protected $model = SshKey::class; 14 | 15 | public function definition(): array 16 | { 17 | return [ 18 | 'user_id' => 1, 19 | 'name' => $this->faker->name(), 20 | 'public_key' => 'public-key-content', 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /database/factories/WorkflowRunFactory.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class WorkflowRunFactory extends Factory 11 | { 12 | /** 13 | * Define the model's default state. 14 | * 15 | * @return array 16 | */ 17 | public function definition(): array 18 | { 19 | return [ 20 | // 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /public/build/assets/index-l2mI7SCD.js: -------------------------------------------------------------------------------- 1 | import{r as u}from"./app-8WgsWSPq.js";import{d as z}from"./index-C6tLKN69.js";function c(r){const[h,e]=u.useState(void 0);return z(()=>{if(r){e({width:r.offsetWidth,height:r.offsetHeight});const f=new ResizeObserver(i=>{if(!Array.isArray(i)||!i.length)return;const b=i[0];let o,t;if("borderBoxSize"in b){const s=b.borderBoxSize,d=Array.isArray(s)?s[0]:s;o=d.inlineSize,t=d.blockSize}else o=r.offsetWidth,t=r.offsetHeight;e({width:o,height:t})});return f.observe(r,{box:"border-box"}),()=>f.unobserve(r)}else e(void 0)},[r]),h}export{c as u}; 2 | -------------------------------------------------------------------------------- /resources/svg/ftp.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | -------------------------------------------------------------------------------- /resources/svg/ufw.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | -------------------------------------------------------------------------------- /resources/views/ssh/services/redis/uninstall.blade.php: -------------------------------------------------------------------------------- 1 | sudo service redis stop 2 | 3 | sudo DEBIAN_FRONTEND=noninteractive apt-get remove redis-server -y 4 | 5 | sudo rm -rf /etc/redis 6 | sudo rm -rf /var/lib/redis 7 | sudo rm -rf /var/log/redis 8 | sudo rm -rf /var/run/redis 9 | sudo rm -rf /var/run/redis/redis-server.pid 10 | sudo rm -rf /var/run/redis/redis-server.sock 11 | sudo rm -rf /var/run/redis/redis-server.sock 12 | 13 | sudo DEBIAN_FRONTEND=noninteractive sudo apt-get autoremove -y 14 | 15 | sudo DEBIAN_FRONTEND=noninteractive sudo apt-get autoclean -y 16 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | New Features | Bug Fixes | Security Fixes | 6 | |---------|--------------|-----------|----------------| 7 | | 0.x | ❌ | ❌ | ❌ | 8 | | 1.x | ❌ | ❌ | ❌ | 9 | | 2.x | ❌ | ❌ | ❌ | 10 | | 3.x | ✅ | ✅ | ✅ | 11 | 12 | ## Reporting a Vulnerability 13 | 14 | If you see a vulnerability, please open an issue or report it directly to me (sa.vaziry@gmail.com) 15 | -------------------------------------------------------------------------------- /public/api-docs/openapi/schemas/Project.yaml: -------------------------------------------------------------------------------- 1 | type: object 2 | properties: 3 | id: 4 | type: integer 5 | example: 1 6 | name: 7 | type: string 8 | example: 'my-project' 9 | role: 10 | type: string 11 | enum: ['owner', 'admin', 'developer', 'viewer'] 12 | nullable: true 13 | example: 'owner' 14 | created_at: 15 | type: string 16 | format: date-time 17 | updated_at: 18 | type: string 19 | format: date-time 20 | users: 21 | type: array 22 | items: 23 | $ref: './ProjectUser.yaml' 24 | nullable: true 25 | -------------------------------------------------------------------------------- /app/Actions/Server/RebootServer.php: -------------------------------------------------------------------------------- 1 | os()->reboot(); 15 | $server->status = ServerStatus::DISCONNECTED; 16 | $server->save(); 17 | } catch (Throwable) { 18 | $server = $server->checkConnection(); 19 | } 20 | 21 | return $server; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /resources/js/types/script-execution.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerLog } from '@/types/server-log'; 2 | import { Server } from './server'; 3 | 4 | export interface ScriptExecution { 5 | id: number; 6 | script_id: number; 7 | server_id: number; 8 | server?: Server; 9 | user_id: number; 10 | server_log_id: number; 11 | log: ServerLog; 12 | user: string; 13 | variables: string[]; 14 | status: string; 15 | status_color: 'gray' | 'success' | 'info' | 'warning' | 'danger'; 16 | created_at: string; 17 | updated_at: string; 18 | 19 | [key: string]: unknown; 20 | } 21 | -------------------------------------------------------------------------------- /resources/views/ssh/os/extract.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $extension = pathinfo($path, PATHINFO_EXTENSION); 3 | @endphp 4 | 5 | @if($extension === 'zip') 6 | unzip -o {{ $path }} -d {{ $destination }} 7 | @elseif($extension === 'tar')) 8 | tar -xf {{ $path }} -C {{ $destination }} 9 | @elseif(in_array($extension, ['gz', 'tar.gz'])) 10 | tar -xzf {{ $path }} -C {{ $destination }} 11 | @elseif(in_array($extension, ['bz2', 'tar.bz2'])) 12 | tar -xjf {{ $path }} -C {{ $destination }} 13 | @else 14 | echo "Unsupported archive format: {{ $extension }}" 15 | @endif 16 | -------------------------------------------------------------------------------- /app/NotificationChannels/Email/NotificationMail.php: -------------------------------------------------------------------------------- 1 | subject = $subject; 16 | } 17 | 18 | public function build(): self 19 | { 20 | return $this->html($this->text); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /public/build/assets/check-updates-BIqGn_DG.js: -------------------------------------------------------------------------------- 1 | import{v as r,j as s}from"./app-8WgsWSPq.js";import{B as i}from"./button-Cfqokzhp.js";import{R as o}from"./refresh-cw-v4O_-xG6.js";/* empty css */import"./utils-DDOqEnVW.js";import"./index-CN-FHsb7.js";import"./createLucideIcon-COM2DoSP.js";function u(){const t=r(),e=()=>{t.get(route("plugins.updates"))};return s.jsxs(i,{variant:"outline",onClick:e,disabled:t.processing,children:[t.processing?s.jsx(o,{className:"animate-spin"}):s.jsx(o,{}),s.jsx("span",{className:"hidden lg:block",children:"Check for Updates"})]})}export{u as default}; 2 | -------------------------------------------------------------------------------- /app/Enums/LoadBalancerMethod.php: -------------------------------------------------------------------------------- 1 | value; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/WorkflowActions/Site/CreateNodeJsSite.php: -------------------------------------------------------------------------------- 1 | 'nodejs', 11 | 'port' => 'Port to run the Node.js application on, example: 3000', 12 | 'source_control' => 'Source control ID', 13 | 'repository' => 'organization/repository', 14 | 'branch' => 'Branch to deploy, example: main', 15 | ]); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /database/factories/BackupFactory.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class BackupFactory extends Factory 13 | { 14 | public function definition(): array 15 | { 16 | return [ 17 | 'type' => 'database', 18 | 'interval' => '0 * * * *', 19 | 'keep_backups' => 10, 20 | 'status' => BackupStatus::RUNNING, 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /resources/svg/local.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | -------------------------------------------------------------------------------- /app/Actions/Worker/GetWorkerLogs.php: -------------------------------------------------------------------------------- 1 | server->processManager(); 15 | 16 | /** @var ProcessManager $handler */ 17 | $handler = $service->handler(); 18 | 19 | return $handler->getLogs($worker->user, $worker->getLogFile()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Middleware/ValidateSignature.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 'fbclid', 16 | // 'utm_campaign', 17 | // 'utm_content', 18 | // 'utm_medium', 19 | // 'utm_source', 20 | // 'utm_term', 21 | ]; 22 | } 23 | -------------------------------------------------------------------------------- /app/SSH/OS/Cron.php: -------------------------------------------------------------------------------- 1 | server->ssh()->exec( 18 | view('ssh.cron.update', [ 19 | 'cron' => $cron, 20 | 'user' => $user, 21 | ]), 22 | 'update-cron' 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /public/build/assets/index-DUU4w66S.js: -------------------------------------------------------------------------------- 1 | import{g as p,b as u,r as f,j as l}from"./app-8WgsWSPq.js";import{b as v}from"./utils-DDOqEnVW.js";var e=u();const h=p(e);var d=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],D=d.reduce((r,t)=>{const s=v(`Primitive.${t}`),i=f.forwardRef((o,a)=>{const{asChild:m,...n}=o,c=m?s:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),l.jsx(c,{...n,ref:a})});return i.displayName=`Primitive.${t}`,{...r,[t]:i}},{});function b(r,t){r&&e.flushSync(()=>r.dispatchEvent(t))}export{D as P,h as R,b as d,e as r}; 2 | -------------------------------------------------------------------------------- /resources/views/ssh/services/process-manager/supervisor/delete-worker.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo supervisorctl stop {{ $id }}:*; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo rm -rf ~/.logs/workers/{{ $id }}.log; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! sudo rm -rf /etc/supervisor/conf.d/{{ $id }}.conf; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | 13 | if ! sudo supervisorctl reread; then 14 | echo 'VITO_SSH_ERROR' && exit 1 15 | fi 16 | 17 | if ! sudo supervisorctl update; then 18 | echo 'VITO_SSH_ERROR' && exit 1 19 | fi 20 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | withPaths([ 9 | __DIR__.'/app', 10 | __DIR__.'/bootstrap/app.php', 11 | __DIR__.'/config', 12 | __DIR__.'/database', 13 | __DIR__.'/public', 14 | ]) 15 | ->withPreparedSets( 16 | deadCode: true, 17 | codeQuality: true, 18 | typeDeclarations: true, 19 | privatization: true, 20 | earlyReturn: true, 21 | strictBooleans: true, 22 | ) 23 | ->withPhpSets(); 24 | -------------------------------------------------------------------------------- /resources/views/ssh/modern-deployment/link-resources.blade.php: -------------------------------------------------------------------------------- 1 | @php($sharedResources = data_get($site->type_data, 'modern_deployment_shared_resources', [])) 2 | 3 | cd {{ $site->basePath() }}/source 4 | git stash 5 | git clean -f 6 | git pull origin {{ $site->branch }} 7 | 8 | @if (count($sharedResources) > 0) 9 | @foreach ($sharedResources as $resource) 10 | rm -rf {{ $releasePath }}/{{ $resource }} 11 | ln -sfn {{ $site->basePath() }}/source/{{ $resource }} {{ $releasePath }}/{{ $resource }} 12 | echo "{{ $resource }} linked" 13 | @endforeach 14 | @endif 15 | 16 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mysql/update-user.blade.php: -------------------------------------------------------------------------------- 1 | @if ($newPassword) 2 | if ! sudo mysql -e "ALTER USER '{{ $username }}'@'{{ $host }}' IDENTIFIED BY '{{ $newPassword }}'"; then 3 | echo 'VITO_SSH_ERROR' && exit 1 4 | fi 5 | @endif 6 | 7 | @if ($newHost && $newHost != $host) 8 | if ! sudo mysql -e "RENAME USER '{{ $username }}'@'{{ $host }}' TO '{{ $username }}'@'{{ $newHost }}'"; then 9 | echo 'VITO_SSH_ERROR' && exit 1 10 | fi 11 | @endif 12 | 13 | if ! sudo mysql -e "FLUSH PRIVILEGES"; then 14 | echo 'VITO_SSH_ERROR' && exit 1 15 | fi 16 | 17 | echo "Command executed" -------------------------------------------------------------------------------- /app/Enums/SslType.php: -------------------------------------------------------------------------------- 1 | 'default', 20 | }; 21 | } 22 | 23 | public function getText(): string 24 | { 25 | return $this->value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/Notifications/GenericNotification.php: -------------------------------------------------------------------------------- 1 | message; 14 | } 15 | 16 | public function toEmail(object $notifiable): MailMessage 17 | { 18 | return (new MailMessage) 19 | ->subject(__('Notification')) 20 | ->line($this->message); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/SSH/OS/Composer.php: -------------------------------------------------------------------------------- 1 | server->ssh($site->user)->exec( 16 | view('ssh.composer.composer-install', [ 17 | 'path' => $site->path, 18 | 'phpVersion' => $site->php_version, 19 | ]), 20 | 'composer-install', 21 | $site->id 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Traits/NormalizesWebDirectory.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/mariadb/update-user.blade.php: -------------------------------------------------------------------------------- 1 | @if ($newPassword) 2 | if ! sudo mariadb -e "ALTER USER '{{ $username }}'@'{{ $host }}' IDENTIFIED BY '{{ $newPassword }}'"; then 3 | echo 'VITO_SSH_ERROR' && exit 1 4 | fi 5 | @endif 6 | 7 | @if ($newHost && $newHost != $host) 8 | if ! sudo mariadb -e "RENAME USER '{{ $username }}'@'{{ $host }}' TO '{{ $username }}'@'{{ $newHost }}'"; then 9 | echo 'VITO_SSH_ERROR' && exit 1 10 | fi 11 | @endif 12 | 13 | if ! sudo mariadb -e "FLUSH PRIVILEGES"; then 14 | echo 'VITO_SSH_ERROR' && exit 1 15 | fi 16 | 17 | echo "Command executed" -------------------------------------------------------------------------------- /app/Actions/SourceControl/DeleteSourceControl.php: -------------------------------------------------------------------------------- 1 | sites()->exists()) { 13 | throw ValidationException::withMessages([ 14 | 'source_control' => __('This source control is being used by a site.'), 15 | ]); 16 | } 17 | 18 | $sourceControl->delete(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /database/factories/BackupFileFactory.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class BackupFileFactory extends Factory 12 | { 13 | public function definition(): array 14 | { 15 | return [ 16 | 'name' => $this->faker->slug().'-'.now()->format('YmdHis'), 17 | 'size' => $this->faker->numberBetween(1000, 10000000), 18 | 'status' => \App\Enums\BackupFileStatus::CREATED, 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/factories/DatabaseFactory.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class DatabaseFactory extends Factory 13 | { 14 | protected $model = Database::class; 15 | 16 | public function definition(): array 17 | { 18 | return [ 19 | 'server_id' => 1, 20 | 'name' => $this->faker->userName, 21 | 'status' => DatabaseStatus::READY, 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /database/factories/ProjectFactory.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class ProjectFactory extends Factory 13 | { 14 | protected $model = Project::class; 15 | 16 | public function definition(): array 17 | { 18 | return [ 19 | 'name' => $this->faker->name(), 20 | 'created_at' => Carbon::now(), 21 | 'updated_at' => Carbon::now(), 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /database/migrations/2025_01_25_193815_drop_telescope_tables.php: -------------------------------------------------------------------------------- 1 | getConnection()); 11 | 12 | $schema->dropIfExists('telescope_entries_tags'); 13 | $schema->dropIfExists('telescope_entries'); 14 | $schema->dropIfExists('telescope_monitoring'); 15 | } 16 | 17 | public function down(): void 18 | { 19 | // 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/seeders/CronJobsSeeder.php: -------------------------------------------------------------------------------- 1 | create([ 17 | 'server_id' => $server->id, 18 | 'command' => 'php /home/vito/'.$server->project->name.'.com/artisan schedule:run', 19 | ]); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Actions/ServerProvider/DeleteServerProvider.php: -------------------------------------------------------------------------------- 1 | servers()->exists()) { 13 | throw ValidationException::withMessages([ 14 | 'provider' => 'This server provider is being used by a server.', 15 | ]); 16 | } 17 | 18 | $serverProvider->delete(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/AdminController.php: -------------------------------------------------------------------------------- 1 | 'success', 17 | self::ADDING => 'warning', 18 | self::DELETING => 'danger', 19 | }; 20 | } 21 | 22 | public function getText(): string 23 | { 24 | return $this->value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Helpers/Notifier.php: -------------------------------------------------------------------------------- 1 | backups()->exists()) { 13 | throw ValidationException::withMessages([ 14 | 'provider' => __('This storage provider is being used by a backup.'), 15 | ]); 16 | } 17 | 18 | $storageProvider->delete(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Enums/DatabaseUserPermission.php: -------------------------------------------------------------------------------- 1 | 'default', 17 | self::WRITE => 'info', 18 | self::ADMIN => 'warning', 19 | }; 20 | } 21 | 22 | public function getText(): string 23 | { 24 | return $this->value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/ValidationRules/DomainRule.php: -------------------------------------------------------------------------------- 1 | translate(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /public/build/assets/logs-B4d6Djcu.js: -------------------------------------------------------------------------------- 1 | import{c as h}from"./createLucideIcon-COM2DoSP.js";/** 2 | * @license lucide-react v0.475.0 - ISC 3 | * 4 | * This source code is licensed under the ISC license. 5 | * See the LICENSE file in the root directory of this source tree. 6 | */const e=[["path",{d:"M13 12h8",key:"h98zly"}],["path",{d:"M13 18h8",key:"oe0vm4"}],["path",{d:"M13 6h8",key:"15sg57"}],["path",{d:"M3 12h1",key:"lp3yf2"}],["path",{d:"M3 18h1",key:"1eiwyy"}],["path",{d:"M3 6h1",key:"rgxa97"}],["path",{d:"M8 12h1",key:"1con00"}],["path",{d:"M8 18h1",key:"13wk12"}],["path",{d:"M8 6h1",key:"tn6mkg"}]],a=h("Logs",e);export{a as L}; 7 | -------------------------------------------------------------------------------- /app/Http/Middleware/HandleAppearance.php: -------------------------------------------------------------------------------- 1 | cookie('appearance') ?? 'system'); 20 | 21 | return $next($request); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Traits/HasProjectThroughServer.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function project(): HasOneThrough 15 | { 16 | return $this->hasOneThrough( 17 | Project::class, 18 | Server::class, 19 | 'id', 20 | 'id', 21 | 'server_id', 22 | 'project_id' 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/ValidationRules/SshKeyRule.php: -------------------------------------------------------------------------------- 1 | translate(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /public/build/assets/columns-Mgli88YL.js: -------------------------------------------------------------------------------- 1 | import{j as r}from"./app-8WgsWSPq.js";import{D as t}from"./date-time-THKTDY8S.js";import{B as a}from"./badge-Lxm3AxQ6.js";/* empty css */import"./utils-DDOqEnVW.js";import"./index-CN-FHsb7.js";const m=[{accessorKey:"id",header:"ID",enableColumnFilter:!0,enableSorting:!0},{accessorKey:"created_at",header:"Created at",enableColumnFilter:!0,enableSorting:!0,cell:({row:e})=>r.jsx(t,{date:e.original.created_at})},{accessorKey:"status",header:"Status",enableColumnFilter:!0,enableSorting:!0,cell:({row:e})=>r.jsx(a,{variant:e.original.status_color,children:e.original.status})}];export{m as columns}; 2 | -------------------------------------------------------------------------------- /app/Enums/DeploymentStatus.php: -------------------------------------------------------------------------------- 1 | 'warning', 17 | self::FINISHED => 'success', 18 | self::FAILED => 'danger', 19 | }; 20 | } 21 | 22 | public function getText(): string 23 | { 24 | return $this->value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Enums/WorkflowRunStatus.php: -------------------------------------------------------------------------------- 1 | 'warning', 17 | self::COMPLETED => 'success', 18 | self::FAILED => 'danger', 19 | }; 20 | } 21 | 22 | public function getText(): string 23 | { 24 | return $this->value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /database/factories/ScriptFactory.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class ScriptFactory extends Factory 13 | { 14 | protected $model = Script::class; 15 | 16 | public function definition(): array 17 | { 18 | return [ 19 | 'name' => $this->faker->name(), 20 | 'content' => 'ls -la', 21 | 'created_at' => Carbon::now(), 22 | 'updated_at' => Carbon::now(), 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /resources/views/ssh/modern-deployment/disable.blade.php: -------------------------------------------------------------------------------- 1 | @php($tmpPath = $site->basePath() . '-tmp') 2 | 3 | LAST_RELEASE_PATH=$(readlink {{ $site->basePath() . '/current' }}) 4 | 5 | mv $LAST_RELEASE_PATH {{ $tmpPath }} 6 | 7 | @if (count($sharedResources) > 0) 8 | @foreach ($sharedResources as $resource) 9 | unlink {{ $tmpPath }}/{{ $resource }} 10 | mv {{ $site->basePath() }}/source/{{ $resource }} {{ $tmpPath }}/{{ $resource }} 11 | @endforeach 12 | @endif 13 | 14 | rm -rf {{ $site->basePath() }} 15 | mv {{ $tmpPath }} {{ $site->basePath() }} 16 | 17 | cd {{ $site->basePath() }} 18 | git stash 19 | git clean -f 20 | -------------------------------------------------------------------------------- /app/Enums/CommandExecutionStatus.php: -------------------------------------------------------------------------------- 1 | 'warning', 17 | self::COMPLETED => 'success', 18 | self::FAILED => 'danger', 19 | }; 20 | } 21 | 22 | public function getText(): string 23 | { 24 | return $this->value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Enums/ScriptExecutionStatus.php: -------------------------------------------------------------------------------- 1 | 'warning', 17 | self::COMPLETED => 'success', 18 | self::FAILED => 'danger', 19 | }; 20 | } 21 | 22 | public function getText(): string 23 | { 24 | return $this->value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/StorageProviders/StorageProvider.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | public function validationRules(): array; 16 | 17 | /** 18 | * @param array $input 19 | * @return array 20 | */ 21 | public function credentialData(array $input): array; 22 | 23 | public function connect(): bool; 24 | 25 | public function ssh(Server $server): Storage; 26 | } 27 | -------------------------------------------------------------------------------- /database/factories/NotificationChannelFactory.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class NotificationChannelFactory extends Factory 12 | { 13 | public function definition(): array 14 | { 15 | return [ 16 | 'label' => $this->faker->text(10), 17 | 'provider' => 'email', 18 | 'data' => [ 19 | 'email' => $this->faker->email, 20 | ], 21 | 'connected' => 1, 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /database/migrations/2025_03_16_081225_rename_queues_to_workers.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('site_id')->nullable()->change(); 14 | }); 15 | } 16 | 17 | public function down(): void 18 | { 19 | Schema::rename('workers', 'queues'); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /resources/js/pages/plugins/components/check-updates.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from '@/components/ui/button'; 2 | import { useForm } from '@inertiajs/react'; 3 | import { RefreshCw } from 'lucide-react'; 4 | 5 | export default function CheckForUpdates() { 6 | const form = useForm(); 7 | 8 | const submit = () => { 9 | form.get(route('plugins.updates')); 10 | }; 11 | 12 | return ( 13 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /resources/views/ssh/os/cleanup.blade.php: -------------------------------------------------------------------------------- 1 | # Update package lists 2 | sudo DEBIAN_FRONTEND=noninteractive apt-get update -y 3 | 4 | # Remove unnecessary dependencies 5 | sudo DEBIAN_FRONTEND=noninteractive apt-get autoremove --purge -y 6 | 7 | # Clear package cache 8 | sudo DEBIAN_FRONTEND=noninteractive apt-get clean -y 9 | 10 | # Remove old configuration files 11 | sudo DEBIAN_FRONTEND=noninteractive apt-get purge -y $(dpkg -l | grep '^rc' | awk '{print $2}') 12 | 13 | # Clear temporary files 14 | sudo rm -rf /tmp/* 15 | 16 | # Clear journal logs 17 | sudo DEBIAN_FRONTEND=noninteractive journalctl --vacuum-time=1d 18 | 19 | echo "Cleanup completed." 20 | -------------------------------------------------------------------------------- /database/migrations/2024_10_06_160213_add_soft_deletes_to_ssh_keys.php: -------------------------------------------------------------------------------- 1 | softDeletes(); 13 | }); 14 | } 15 | 16 | public function down(): void 17 | { 18 | Schema::table('ssh_keys', function (Blueprint $table): void { 19 | $table->dropSoftDeletes(); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /app/Actions/Database/DeleteDatabaseUser.php: -------------------------------------------------------------------------------- 1 | database(); 16 | /** @var Database $handler */ 17 | $handler = $service->handler(); 18 | $handler->deleteUser($databaseUser->username, $databaseUser->host); 19 | $databaseUser->delete(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/factories/ServiceFactory.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class ServiceFactory extends Factory 13 | { 14 | protected $model = Service::class; 15 | 16 | public function definition(): array 17 | { 18 | return [ 19 | 'server_id' => 1, 20 | 'type' => 'webserver', 21 | 'name' => 'nginx', 22 | 'version' => 'latest', 23 | 'status' => ServiceStatus::READY, 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /database/migrations/2023_08_17_231824_update_backups_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('name'); 13 | }); 14 | } 15 | 16 | public function down(): void 17 | { 18 | Schema::table('backups', function (Blueprint $table): void { 19 | $table->string('name')->nullable(); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2024_10_04_190341_add_soft_deletes_to_databases.php: -------------------------------------------------------------------------------- 1 | softDeletes(); 13 | }); 14 | } 15 | 16 | public function down(): void 17 | { 18 | Schema::table('databases', function (Blueprint $table): void { 19 | $table->dropSoftDeletes(); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2025_01_29_192733_add_email_to_ssls_table.php: -------------------------------------------------------------------------------- 1 | string('email')->nullable(); 13 | }); 14 | } 15 | 16 | public function down(): void 17 | { 18 | Schema::table('ssls', function (Blueprint $table): void { 19 | $table->dropColumn('email'); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /resources/js/components/text-link.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils'; 2 | import { Link } from '@inertiajs/react'; 3 | import { ComponentProps } from 'react'; 4 | 5 | type LinkProps = ComponentProps; 6 | 7 | export default function TextLink({ className = '', children, ...props }: LinkProps) { 8 | return ( 9 | 16 | {children} 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /resources/js/types/deployment.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerLog } from '@/types/server-log'; 2 | 3 | export interface Deployment { 4 | id: number; 5 | site_id: number; 6 | deployment_script_id: number; 7 | log_id: number; 8 | log: ServerLog; 9 | commit_id: string; 10 | commit_id_short: string; 11 | commit_data: { 12 | name?: string; 13 | email?: string; 14 | message?: string; 15 | url?: string; 16 | }; 17 | status: string; 18 | status_color: 'gray' | 'success' | 'info' | 'warning' | 'danger'; 19 | release?: string; 20 | active: boolean; 21 | created_at: string; 22 | updated_at: string; 23 | 24 | [key: string]: unknown; 25 | } 26 | -------------------------------------------------------------------------------- /app/Models/PersonalAccessToken.php: -------------------------------------------------------------------------------- 1 | $abilities 16 | * @property Carbon $last_used_at 17 | * @property Carbon $created_at 18 | * @property Carbon $updated_at 19 | */ 20 | class PersonalAccessToken extends SanctumPersonalAccessToken 21 | { 22 | use HasTimezoneTimestamps; 23 | } 24 | -------------------------------------------------------------------------------- /database/migrations/2024_10_06_091631_add_log_id_to_ssls.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('log_id')->nullable(); 13 | }); 14 | } 15 | 16 | public function down(): void 17 | { 18 | Schema::table('ssls', function (Blueprint $table): void { 19 | $table->dropColumn('log_id'); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2025_06_13_162729_update_servers_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('type'); 13 | $table->dropColumn('type_data'); 14 | }); 15 | } 16 | 17 | public function down(): void 18 | { 19 | Schema::table('servers', function (Blueprint $table) { 20 | // 21 | }); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /database/migrations/2025_06_14_111059_add_name_to_workers_table.php: -------------------------------------------------------------------------------- 1 | string('name')->nullable()->index(); 13 | }); 14 | } 15 | 16 | public function down(): void 17 | { 18 | Schema::table('workers', function (Blueprint $table) { 19 | // $table->dropColumn('name'); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /public/api-docs/swagger-ui/swagger-initializer.js: -------------------------------------------------------------------------------- 1 | window.onload = function() { 2 | // 3 | 4 | // the following lines will be replaced by docker/configurator, when it runs in a docker-container 5 | window.ui = SwaggerUIBundle({ 6 | url: "https://petstore.swagger.io/v2/swagger.json", 7 | dom_id: '#swagger-ui', 8 | deepLinking: true, 9 | presets: [ 10 | SwaggerUIBundle.presets.apis, 11 | SwaggerUIStandalonePreset 12 | ], 13 | plugins: [ 14 | SwaggerUIBundle.plugins.DownloadUrl 15 | ], 16 | layout: "StandaloneLayout" 17 | }); 18 | 19 | // 20 | }; 21 | -------------------------------------------------------------------------------- /public/build/assets/textarea-CW5NSbOn.js: -------------------------------------------------------------------------------- 1 | import{j as i}from"./app-8WgsWSPq.js";import{c as t}from"./utils-DDOqEnVW.js";function n({className:r,...e}){return i.jsx("textarea",{"data-slot":"textarea",className:t("border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",r),...e})}export{n as T}; 2 | -------------------------------------------------------------------------------- /app/Actions/ServerLog/UpdateLog.php: -------------------------------------------------------------------------------- 1 | $input 13 | * 14 | * @throws ValidationException 15 | */ 16 | public function update(ServerLog $serverLog, array $input): void 17 | { 18 | Validator::make($input, [ 19 | 'path' => 'required', 20 | ])->validate(); 21 | 22 | $serverLog->update([ 23 | 'name' => $input['path'], 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /public/api-docs/openapi/schemas/ProjectUser.yaml: -------------------------------------------------------------------------------- 1 | type: object 2 | properties: 3 | id: 4 | type: integer 5 | example: 1 6 | user_id: 7 | type: integer 8 | nullable: true 9 | example: 1 10 | project_id: 11 | type: integer 12 | example: 1 13 | project_name: 14 | type: string 15 | nullable: true 16 | example: 'my-project' 17 | email: 18 | type: string 19 | nullable: true 20 | example: 'user@example.com' 21 | role: 22 | type: string 23 | enum: ['owner', 'admin', 'developer', 'viewer'] 24 | example: 'owner' 25 | type: 26 | type: string 27 | enum: ['user', 'invitation'] 28 | example: 'user' 29 | -------------------------------------------------------------------------------- /resources/js/hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | const MOBILE_BREAKPOINT = 768; 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = useState(); 7 | 8 | useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); 10 | 11 | const onChange = () => { 12 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); 13 | }; 14 | 15 | mql.addEventListener('change', onChange); 16 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); 17 | 18 | return () => mql.removeEventListener('change', onChange); 19 | }, []); 20 | 21 | return !!isMobile; 22 | } 23 | -------------------------------------------------------------------------------- /resources/js/hooks/use-page-active.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | export function usePageActive() { 4 | const getActive = () => typeof document !== 'undefined' && !document.hidden; 5 | 6 | const [active, setActive] = useState(getActive()); 7 | 8 | useEffect(() => { 9 | const update = () => setActive(getActive()); 10 | document.addEventListener('visibilitychange', update); 11 | window.addEventListener('focus', update); 12 | return () => { 13 | document.removeEventListener('visibilitychange', update); 14 | window.removeEventListener('focus', update); 15 | }; 16 | }, []); 17 | 18 | return active; 19 | } 20 | -------------------------------------------------------------------------------- /resources/views/ssh/services/database/postgresql/backup.blade.php: -------------------------------------------------------------------------------- 1 | if ! sudo -u postgres pg_dump -d {{ $database }} -f /var/lib/postgresql/{{ $file }}.sql; then 2 | echo 'VITO_SSH_ERROR' && exit 1 3 | fi 4 | 5 | if ! sudo mv /var/lib/postgresql/{{ $file }}.sql /home/vito/{{ $file }}.sql; then 6 | echo 'VITO_SSH_ERROR' && exit 1 7 | fi 8 | 9 | if ! sudo chown vito:vito /home/vito/{{ $file }}.sql; then 10 | echo 'VITO_SSH_ERROR' && exit 1 11 | fi 12 | 13 | if ! DEBIAN_FRONTEND=noninteractive zip {{ $file }}.zip {{ $file }}.sql; then 14 | echo 'VITO_SSH_ERROR' && exit 1 15 | fi 16 | 17 | if ! rm {{ $file }}.sql; then 18 | echo 'VITO_SSH_ERROR' && exit 1 19 | fi 20 | -------------------------------------------------------------------------------- /resources/views/ssh/services/webserver/nginx/vhost-blocks/php.blade.php: -------------------------------------------------------------------------------- 1 | #[php] 2 | @php 3 | $phpSocket = "unix:/var/run/php/php{$site->php_version}-fpm.sock"; 4 | if ($site->isIsolated()) { 5 | $phpSocket = "unix:/run/php/php{$site->php_version}-fpm-{$site->user}.sock"; 6 | } 7 | @endphp 8 | location / { 9 | try_files $uri $uri/ /index.php?$query_string; 10 | } 11 | location ~ \.php$ { 12 | fastcgi_pass {{ $phpSocket }}; 13 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; 14 | include fastcgi_params; 15 | fastcgi_hide_header X-Powered-By; 16 | } 17 | index index.php index.html; 18 | error_page 404 /index.php; 19 | #[/php] 20 | -------------------------------------------------------------------------------- /database/migrations/2023_10_01_120250_create_projects_table.php: -------------------------------------------------------------------------------- 1 | id(); 13 | $table->bigInteger('user_id'); 14 | $table->string('name'); 15 | $table->timestamps(); 16 | }); 17 | } 18 | 19 | public function down(): void 20 | { 21 | Schema::dropIfExists('projects'); 22 | } 23 | }; 24 | --------------------------------------------------------------------------------