Migrate to HTMX (#114)

Dropped Livewire
Added HTMX
Added Blade code lint
Drop Mysql and Redis
Migrate to SQLite
This commit is contained in:
Saeed Vaziry
2024-03-06 17:02:59 +01:00
committed by GitHub
parent 5b2c419e91
commit b2083fc6b2
486 changed files with 8609 additions and 8707 deletions

View File

@ -0,0 +1,104 @@
<?php
namespace App\Http\Controllers;
use App\Actions\Site\UpdateBranch;
use App\Actions\Site\UpdateDeploymentScript;
use App\Actions\Site\UpdateEnv;
use App\Exceptions\SourceControlIsNotConnected;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Deployment;
use App\Models\Server;
use App\Models\Site;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class ApplicationController extends Controller
{
public function deploy(Server $server, Site $site): HtmxResponse
{
try {
$site->deploy();
Toast::success('Deployment started!');
} catch (SourceControlIsNotConnected $e) {
Toast::error($e->getMessage());
return htmx()->redirect(route('source-controls'));
}
return htmx()->back();
}
public function showDeploymentLog(Server $server, Site $site, Deployment $deployment): RedirectResponse
{
return back()->with('content', $deployment->log->content);
}
public function updateDeploymentScript(Server $server, Site $site, Request $request): RedirectResponse
{
app(UpdateDeploymentScript::class)->update($site, $request->input());
Toast::success('Deployment script updated!');
return back();
}
public function updateBranch(Server $server, Site $site, Request $request): RedirectResponse
{
app(UpdateBranch::class)->update($site, $request->input());
Toast::success('Branch updated!');
return back();
}
public function getEnv(Server $server, Site $site): RedirectResponse
{
return back()->with('env', $site->getEnv());
}
public function updateEnv(Server $server, Site $site, Request $request): RedirectResponse
{
app(UpdateEnv::class)->update($site, $request->input());
Toast::success('Env updated!');
return back();
}
public function enableAutoDeployment(Server $server, Site $site): RedirectResponse
{
if (! $site->auto_deployment) {
try {
$site->enableAutoDeployment();
$site->refresh();
Toast::success('Auto deployment has been enabled.');
} catch (SourceControlIsNotConnected) {
Toast::error('Source control is not connected. Check site\'s settings.');
}
}
return back();
}
public function disableAutoDeployment(Server $server, Site $site): RedirectResponse
{
if ($site->auto_deployment) {
try {
$site->disableAutoDeployment();
$site->refresh();
Toast::success('Auto deployment has been disabled.');
} catch (SourceControlIsNotConnected) {
Toast::error('Source control is not connected. Check site\'s settings.');
}
}
return back();
}
}

View File

@ -2,14 +2,41 @@
namespace App\Http\Controllers;
use App\Actions\CronJob\CreateCronJob;
use App\Actions\CronJob\DeleteCronJob;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\CronJob;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class CronjobController extends Controller
{
public function index(Server $server)
public function index(Server $server): View
{
return view('cronjobs.index', [
'server' => $server,
'cronjobs' => $server->cronJobs,
]);
}
public function store(Server $server, Request $request): HtmxResponse
{
app(CreateCronJob::class)->create($server, $request->input());
Toast::success('Cronjob created successfully.');
return htmx()->back();
}
public function destroy(Server $server, CronJob $cronJob): RedirectResponse
{
app(DeleteCronJob::class)->delete($server, $cronJob);
Toast::success('Cronjob deleted successfully.');
return back();
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace App\Http\Controllers;
use App\Actions\Database\CreateBackup;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Backup;
use App\Models\BackupFile;
use App\Models\Database;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class DatabaseBackupController extends Controller
{
public function show(Server $server, Backup $backup): View
{
return view('databases.backups', [
'server' => $server,
'databases' => $server->databases,
'backup' => $backup,
'files' => $backup->files()->orderByDesc('id')->simplePaginate(10),
]);
}
public function run(Server $server, Backup $backup): RedirectResponse
{
$backup->run();
Toast::success('Backup is running.');
return back();
}
public function store(Server $server, Request $request): HtmxResponse
{
app(CreateBackup::class)->create('database', $server, $request->input());
Toast::success('Backup created successfully.');
return htmx()->back();
}
public function destroy(Server $server, Backup $backup): RedirectResponse
{
$backup->delete();
Toast::success('Backup deleted successfully.');
return back();
}
public function restore(Server $server, Backup $backup, BackupFile $backupFile, Request $request): HtmxResponse
{
$this->validate($request, [
'database' => 'required|exists:databases,id',
]);
/** @var Database $database */
$database = Database::query()->findOrFail($request->input('database'));
$backupFile->restore($database);
Toast::success('Backup restored successfully.');
return htmx()->back();
}
public function destroyFile(Server $server, Backup $backup, BackupFile $backupFile): RedirectResponse
{
$backupFile->delete();
Toast::success('Backup file deleted successfully.');
return back();
}
}

View File

@ -2,9 +2,16 @@
namespace App\Http\Controllers;
use App\Models\Backup;
use App\Actions\Database\CreateDatabase;
use App\Actions\Database\CreateDatabaseUser;
use App\Actions\Database\DeleteDatabase;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Database;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class DatabaseController extends Controller
{
@ -12,14 +19,31 @@ public function index(Server $server): View
{
return view('databases.index', [
'server' => $server,
'databases' => $server->databases,
'databaseUsers' => $server->databaseUsers,
'backups' => $server->backups,
]);
}
public function backups(Server $server, Backup $backup): View
public function store(Server $server, Request $request): HtmxResponse
{
return view('databases.backups', [
'server' => $server,
'backup' => $backup,
]);
$database = app(CreateDatabase::class)->create($server, $request->input());
if ($request->input('user')) {
app(CreateDatabaseUser::class)->create($server, $request->input(), [$database->name]);
}
Toast::success('Database created successfully.');
return htmx()->back();
}
public function destroy(Server $server, Database $database): RedirectResponse
{
app(DeleteDatabase::class)->delete($server, $database);
Toast::success('Database deleted successfully.');
return back();
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace App\Http\Controllers;
use App\Actions\Database\CreateDatabaseUser;
use App\Actions\Database\DeleteDatabaseUser;
use App\Actions\Database\LinkUser;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\DatabaseUser;
use App\Models\Server;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class DatabaseUserController extends Controller
{
public function store(Server $server, Request $request): HtmxResponse
{
$database = app(CreateDatabaseUser::class)->create($server, $request->input());
if ($request->input('user')) {
app(CreateDatabaseUser::class)->create($server, $request->input(), [$database->name]);
}
Toast::success('User created successfully.');
return htmx()->back();
}
public function destroy(Server $server, DatabaseUser $databaseUser): RedirectResponse
{
app(DeleteDatabaseUser::class)->delete($server, $databaseUser);
Toast::success('User deleted successfully.');
return back();
}
public function password(Server $server, DatabaseUser $databaseUser): RedirectResponse
{
return back()->with([
'password' => $databaseUser->password,
]);
}
public function link(Server $server, DatabaseUser $databaseUser, Request $request): HtmxResponse
{
app(LinkUser::class)->link($databaseUser, $request->input());
Toast::success('Database linked successfully.');
return htmx()->back();
}
}

View File

@ -2,14 +2,41 @@
namespace App\Http\Controllers;
use App\Actions\FirewallRule\CreateRule;
use App\Actions\FirewallRule\DeleteRule;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\FirewallRule;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class FirewallController extends Controller
{
public function index(Server $server)
public function index(Server $server): View
{
return view('firewall.index', [
'server' => $server,
'rules' => $server->firewallRules,
]);
}
public function store(Server $server, Request $request): HtmxResponse
{
app(CreateRule::class)->create($server, $request->input());
Toast::success('Firewall rule created!');
return htmx()->back();
}
public function destroy(Server $server, FirewallRule $firewallRule): RedirectResponse
{
app(DeleteRule::class)->delete($server, $firewallRule);
Toast::success('Firewall rule deleted!');
return back();
}
}

View File

@ -2,14 +2,84 @@
namespace App\Http\Controllers;
use App\Actions\PHP\ChangeDefaultCli;
use App\Actions\PHP\GetPHPIni;
use App\Actions\PHP\InstallNewPHP;
use App\Actions\PHP\InstallPHPExtension;
use App\Actions\PHP\UninstallPHP;
use App\Actions\PHP\UpdatePHPIni;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
class PHPController extends Controller
{
public function index(Server $server)
public function index(Server $server): View
{
return view('php.index', [
'server' => $server,
'phps' => $server->services()->where('type', 'php')->get(),
'defaultPHP' => $server->defaultService('php'),
]);
}
public function install(Server $server, Request $request): HtmxResponse
{
try {
app(InstallNewPHP::class)->install($server, $request->input());
Toast::success('PHP is being installed!');
} catch (ValidationException $e) {
Toast::error($e->getMessage());
}
return htmx()->back();
}
public function installExtension(Server $server, Request $request): HtmxResponse
{
app(InstallPHPExtension::class)->install($server, $request->input());
Toast::success('PHP extension is being installed! Check the logs');
return htmx()->back();
}
public function defaultCli(Server $server, Request $request): HtmxResponse
{
app(ChangeDefaultCli::class)->change($server, $request->input());
Toast::success('Default PHP CLI is being changed!');
return htmx()->back();
}
public function getIni(Server $server, Request $request): RedirectResponse
{
$ini = app(GetPHPIni::class)->getIni($server, $request->input());
return back()->with('ini', $ini);
}
public function updateIni(Server $server, Request $request): RedirectResponse
{
app(UpdatePHPIni::class)->update($server, $request->input());
Toast::success('PHP ini updated!');
return back();
}
public function uninstall(Server $server, Request $request): RedirectResponse
{
app(UninstallPHP::class)->uninstall($server, $request->input());
Toast::success('PHP is being uninstalled!');
return back();
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Models\Project;
use App\Models\User;
use Illuminate\Contracts\View\View;
class ProjectController extends Controller
{
public function index(): View
{
return view('projects.index');
}
public function switch($projectId)
{
/** @var User $user */
$user = auth()->user();
/** @var Project $project */
$project = $user->projects()->findOrFail($projectId);
$user->current_project_id = $project->id;
$user->save();
return redirect()->route('servers');
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers;
use App\Actions\Queue\CreateQueue;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Queue;
use App\Models\Server;
use App\Models\Site;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class QueueController extends Controller
{
public function index(Server $server, Site $site): View
{
return view('queues.index', [
'server' => $server,
'site' => $site,
'queues' => $site->queues,
]);
}
public function store(Server $server, Site $site, Request $request): HtmxResponse
{
app(CreateQueue::class)->create($site, $request->input());
Toast::success('Queue is being created.');
return htmx()->back();
}
public function action(Server $server, Site $site, Queue $queue, string $action): HtmxResponse
{
$queue->{$action}();
Toast::success('Queue is about to '.$action);
return htmx()->back();
}
public function destroy(Server $server, Site $site, Queue $queue): RedirectResponse
{
$queue->remove();
Toast::success('Queue is being deleted.');
return back();
}
}

View File

@ -2,14 +2,62 @@
namespace App\Http\Controllers;
use App\Actions\SshKey\CreateSshKey;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Server;
use App\Models\SshKey;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class SSHKeyController extends Controller
{
public function index(Server $server)
public function index(Server $server): View
{
return view('server-ssh-keys.index', [
'server' => $server,
'keys' => $server->sshKeys,
]);
}
public function store(Server $server, Request $request): HtmxResponse
{
/** @var \App\Models\SshKey $key */
$key = app(CreateSshKey::class)->create(
$request->user(),
$request->input()
);
$key->deployTo($server);
Toast::success('SSH Key added and being deployed to the server.');
return htmx()->back();
}
public function destroy(Server $server, SshKey $sshKey): RedirectResponse
{
$sshKey->deleteFrom($server);
Toast::success('SSH Key is being deleted.');
return back();
}
public function deploy(Server $server, Request $request): HtmxResponse
{
$this->validate($request, [
'key_id' => 'required|exists:ssh_keys,id',
]);
/** @var SshKey $sshKey */
$sshKey = SshKey::query()->findOrFail($request->input('key_id'));
$sshKey->deployTo($server);
Toast::success('SSH Key is being deployed to the server.');
return htmx()->back();
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers;
use App\Actions\SSL\CreateSSL;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Server;
use App\Models\Site;
use App\Models\Ssl;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class SSLController extends Controller
{
public function index(Server $server, Site $site): View
{
return view('ssls.index', [
'server' => $server,
'site' => $site,
'ssls' => $site->ssls,
]);
}
public function store(Server $server, Site $site, Request $request): HtmxResponse
{
app(CreateSSL::class)->create($site, $request->input());
Toast::success('SSL certificate is being created.');
return htmx()->back();
}
public function destroy(Server $server, Site $site, Ssl $ssl): RedirectResponse
{
$ssl->remove();
Toast::success('SSL certificate is being deleted.');
return back();
}
}

View File

@ -2,27 +2,68 @@
namespace App\Http\Controllers;
use App\Actions\Server\CreateServer;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Server;
use App\Models\ServerProvider;
use App\Models\User;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Throwable;
class ServerController extends Controller
{
public function index()
public function index(): View
{
return view('servers.index');
/** @var User $user */
$user = auth()->user();
$servers = $user->currentProject->servers()->orderByDesc('created_at')->get();
return view('servers.index', compact('servers'));
}
public function create()
public function create(Request $request): View
{
return view('servers.create');
$provider = $request->query('provider', old('provider', \App\Enums\ServerProvider::CUSTOM));
$serverProviders = ServerProvider::query()->where('provider', $provider)->get();
return view('servers.create', [
'serverProviders' => $serverProviders,
'provider' => $provider,
]);
}
public function show(Server $server)
/**
* @throws Throwable
*/
public function store(Request $request): HtmxResponse
{
return view('servers.show', compact('server'));
$server = app(CreateServer::class)->create(
$request->user(),
$request->input()
);
Toast::success('Server created successfully.');
return htmx()->redirect(route('servers.show', ['server' => $server]));
}
public function logs(Server $server)
public function show(Server $server): View
{
return view('servers.logs', compact('server'));
return view('servers.show', [
'server' => $server,
'logs' => $server->logs()->latest()->limit(10)->get(),
]);
}
public function delete(Server $server): RedirectResponse
{
$server->delete();
Toast::success('Server deleted successfully.');
return redirect()->route('servers');
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Http\Controllers;
use App\Models\Server;
use App\Models\ServerLog;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
class ServerLogController extends Controller
{
public function index(Server $server): View
{
return view('server-logs.index', [
'server' => $server,
]);
}
public function show(Server $server, ServerLog $serverLog): RedirectResponse
{
if ($server->id != $serverLog->server_id) {
abort(404);
}
return back()->with([
'content' => $serverLog->content,
]);
}
}

View File

@ -2,12 +2,55 @@
namespace App\Http\Controllers;
use App\Actions\Server\EditServer;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class ServerSettingController extends Controller
{
public function index(Server $server)
public function index(Server $server): View
{
return view('server-settings.index', compact('server'));
}
public function checkConnection(Server $server): RedirectResponse|HtmxResponse
{
$oldStatus = $server->status;
$server = $server->checkConnection();
if ($server->status == 'disconnected') {
Toast::error('Server is disconnected.');
}
if ($server->status == 'ready') {
Toast::success('Server is ready.');
}
if ($oldStatus != $server->status) {
return htmx()->redirect(back()->getTargetUrl());
}
return back();
}
public function reboot(Server $server): HtmxResponse
{
$server->reboot();
return htmx()->redirect(back()->getTargetUrl());
}
public function edit(Request $request, Server $server): RedirectResponse
{
app(EditServer::class)->edit($server, $request->input());
Toast::success('Server updated.');
return back();
}
}

View File

@ -2,14 +2,46 @@
namespace App\Http\Controllers;
use App\Facades\Toast;
use App\Models\Server;
use App\Models\Service;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
class ServiceController extends Controller
{
public function index(Server $server)
public function index(Server $server): View
{
return view('services.index', [
'server' => $server,
'services' => $server->services,
]);
}
public function start(Server $server, Service $service): RedirectResponse
{
$service->start();
Toast::success('Service is being started!');
return back();
}
public function stop(Server $server, Service $service): RedirectResponse
{
$service->stop();
Toast::success('Service is being stopped!');
return back();
}
public function restart(Server $server, Service $service): RedirectResponse
{
$service->restart();
Toast::success('Service is being restarted!');
return back();
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Actions\NotificationChannels\AddChannel;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Http\Controllers\Controller;
use App\Models\NotificationChannel;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class NotificationChannelController extends Controller
{
public function index(): View
{
return view('settings.notification-channels.index', [
'channels' => NotificationChannel::query()->latest()->get(),
]);
}
public function add(Request $request): HtmxResponse
{
app(AddChannel::class)->add(
$request->user(),
$request->input()
);
Toast::success('Channel added successfully');
return htmx()->redirect(route('notification-channels'));
}
public function delete(int $id): RedirectResponse
{
$channel = NotificationChannel::query()->findOrFail($id);
$channel->delete();
Toast::success('Channel deleted successfully');
return redirect()->route('notification-channels');
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Actions\User\UpdateUserPassword;
use App\Actions\User\UpdateUserProfileInformation;
use App\Facades\Toast;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class ProfileController extends Controller
{
public function index(): View
{
return view('settings.profile.index');
}
public function info(Request $request): RedirectResponse
{
app(UpdateUserProfileInformation::class)->update(
$request->user(),
$request->input()
);
Toast::success('Profile information updated.');
return back();
}
public function password(Request $request): RedirectResponse
{
app(UpdateUserPassword::class)->update(
$request->user(),
$request->input()
);
Toast::success('Password updated.');
return back();
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Actions\Projects\CreateProject;
use App\Actions\Projects\DeleteProject;
use App\Actions\Projects\UpdateProject;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Http\Controllers\Controller;
use App\Models\Project;
use App\Models\User;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
class ProjectController extends Controller
{
public function index(): View
{
return view('settings.projects.index', [
'projects' => auth()->user()->projects,
]);
}
public function create(Request $request): HtmxResponse
{
app(CreateProject::class)->create($request->user(), $request->input());
Toast::success('Project created.');
return htmx()->redirect(route('projects'));
}
public function update(Request $request, Project $project): HtmxResponse
{
/** @var Project $project */
$project = $request->user()->projects()->findOrFail($project->id);
app(UpdateProject::class)->update($project, $request->input());
Toast::success('Project updated.');
return htmx()->redirect(route('projects'));
}
public function delete(Project $project): RedirectResponse
{
/** @var Project $project */
$project = auth()->user()->projects()->findOrFail($project->id);
try {
app(DeleteProject::class)->delete(auth()->user(), $project);
} catch (ValidationException $e) {
Toast::error($e->getMessage());
return back();
}
Toast::success('Project deleted.');
return back();
}
public function switch($projectId): RedirectResponse
{
/** @var User $user */
$user = auth()->user();
/** @var Project $project */
$project = $user->projects()->findOrFail($projectId);
$user->current_project_id = $project->id;
$user->save();
return redirect()->route('servers');
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Actions\SshKey\CreateSshKey;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Http\Controllers\Controller;
use App\Models\SshKey;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class SSHKeyController extends Controller
{
public function index(): View
{
return view('settings.ssh-keys.index', [
'keys' => SshKey::query()->latest()->get(),
]);
}
public function add(Request $request): HtmxResponse
{
app(CreateSshKey::class)->create(
$request->user(),
$request->input()
);
Toast::success('SSH Key added');
return htmx()->redirect(route('ssh-keys'));
}
public function delete(int $id): RedirectResponse
{
$key = SshKey::query()->findOrFail($id);
$key->delete();
Toast::success('SSH Key deleted');
return redirect()->route('ssh-keys');
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Actions\ServerProvider\CreateServerProvider;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Http\Controllers\Controller;
use App\Models\ServerProvider;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class ServerProviderController extends Controller
{
public function index(): View
{
return view('settings.server-providers.index', [
'providers' => auth()->user()->serverProviders,
]);
}
public function connect(Request $request): HtmxResponse
{
app(CreateServerProvider::class)->create(
$request->user(),
$request->input()
);
Toast::success('Server provider connected.');
return htmx()->redirect(route('server-providers'));
}
/**
* @TODO Update servers using this provider
*/
public function delete(int $id): RedirectResponse
{
$serverProvider = ServerProvider::query()->findOrFail($id);
$serverProvider->delete();
Toast::success('Server provider deleted.');
return back();
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Actions\SourceControl\ConnectSourceControl;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Http\Controllers\Controller;
use App\Models\SourceControl;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
/**
* @TODO Assign user to source control
*/
class SourceControlController extends Controller
{
public function index(): View
{
return view('settings.source-controls.index', [
'sourceControls' => SourceControl::query()->orderByDesc('id')->get(),
]);
}
public function connect(Request $request): HtmxResponse
{
app(ConnectSourceControl::class)->connect(
$request->input(),
);
Toast::success('Source control connected.');
return htmx()->redirect(route('source-controls'));
}
public function delete(int $id): RedirectResponse
{
$sourceControl = SourceControl::query()->findOrFail($id);
$sourceControl->delete();
Toast::success('Source control deleted.');
return redirect()->route('source-controls');
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Actions\StorageProvider\CreateStorageProvider;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Http\Controllers\Controller;
use App\Models\StorageProvider;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class StorageProviderController extends Controller
{
public function index(): View
{
return view('settings.storage-providers.index', [
'providers' => auth()->user()->storageProviders,
]);
}
public function connect(Request $request): HtmxResponse
{
app(CreateStorageProvider::class)->create(
$request->user(),
$request->input()
);
Toast::success('Storage provider connected.');
return htmx()->redirect(route('storage-providers'));
}
/**
* @TODO Update servers using this provider
*/
public function delete(int $id): RedirectResponse
{
$storageProvider = StorageProvider::query()->findOrFail($id);
$storageProvider->delete();
Toast::success('Storage provider deleted.');
return back();
}
}

View File

@ -2,9 +2,16 @@
namespace App\Http\Controllers;
use App\Actions\Site\CreateSite;
use App\Enums\SiteType;
use App\Facades\Toast;
use App\Helpers\HtmxResponse;
use App\Models\Server;
use App\Models\Site;
use App\Models\SourceControl;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class SiteController extends Controller
{
@ -12,13 +19,25 @@ public function index(Server $server): View
{
return view('sites.index', [
'server' => $server,
'sites' => $server->sites()->orderByDesc('id')->get(),
]);
}
public function store(Server $server, Request $request): HtmxResponse
{
$site = app(CreateSite::class)->create($server, $request->input());
Toast::success('Site created');
return htmx()->redirect(route('servers.sites.show', [$server, $site]));
}
public function create(Server $server): View
{
return view('sites.create', [
'server' => $server,
'type' => old('type', request()->query('type', SiteType::LARAVEL)),
'sourceControls' => SourceControl::all(),
]);
}
@ -30,43 +49,12 @@ public function show(Server $server, Site $site): View
]);
}
public function application(Server $server, Site $site): View
public function destroy(Server $server, Site $site): RedirectResponse
{
return view('sites.application', [
'server' => $server,
'site' => $site,
]);
}
$site->remove();
public function ssl(Server $server, Site $site): View
{
return view('sites.ssl', [
'server' => $server,
'site' => $site,
]);
}
Toast::success('Site is being deleted');
public function queues(Server $server, Site $site): View
{
return view('sites.queues', [
'server' => $server,
'site' => $site,
]);
}
public function settings(Server $server, Site $site): View
{
return view('sites.settings', [
'server' => $server,
'site' => $site,
]);
}
public function logs(Server $server, Site $site): View
{
return view('sites.logs', [
'server' => $server,
'site' => $site,
]);
return redirect()->route('servers.sites', $server);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Http\Controllers;
use App\Models\Server;
use App\Models\Site;
use Illuminate\Contracts\View\View;
class SiteLogController extends Controller
{
public function index(Server $server, Site $site): View
{
return view('site-logs.index', [
'server' => $server,
'site' => $site,
]);
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace App\Http\Controllers;
use App\Facades\Toast;
use App\Models\Server;
use App\Models\Site;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Throwable;
class SiteSettingController extends Controller
{
public function index(Server $server, Site $site): View
{
return view('site-settings.index', [
'server' => $server,
'site' => $site,
]);
}
public function getVhost(Server $server, Site $site): RedirectResponse
{
return back()->with('vhost', $server->webserver()->handler()->getVHost($site));
}
public function updateVhost(Server $server, Site $site, Request $request): RedirectResponse
{
$this->validate($request, [
'vhost' => 'required|string',
]);
try {
$server->webserver()->handler()->updateVHost($site, false, $request->input('vhost'));
Toast::success('VHost updated successfully!');
} catch (Throwable $e) {
Toast::error($e->getMessage());
}
return back();
}
public function updatePHPVersion(Server $server, Site $site, Request $request): RedirectResponse
{
$this->validate($request, [
'version' => [
'required',
Rule::exists('services', 'version')->where('type', 'php'),
],
]);
try {
$site->changePHPVersion($request->input('version'));
Toast::success('PHP version updated successfully!');
} catch (Throwable $e) {
Toast::error($e->getMessage());
}
return back();
}
}

View File

@ -2,6 +2,7 @@
namespace App\Http;
use App\Http\Middleware\HandleSSHErrors;
use App\Http\Middleware\ServerIsReadyMiddleware;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
@ -65,5 +66,6 @@ class Kernel extends HttpKernel
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'server-is-ready' => ServerIsReadyMiddleware::class,
'handle-ssh-errors' => HandleSSHErrors::class,
];
}

View File

@ -1,60 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Exceptions\SourceControlIsNotConnected;
use App\Models\Site;
use App\Traits\HasToast;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
use Throwable;
class AutoDeployment extends Component
{
use HasToast;
use RefreshComponentOnBroadcast;
public Site $site;
/**
* @throws Throwable
*/
public function enable(): void
{
if (! $this->site->auto_deployment) {
try {
$this->site->enableAutoDeployment();
$this->site->refresh();
$this->toast()->success(__('Auto deployment has been enabled.'));
} catch (SourceControlIsNotConnected) {
$this->toast()->error(__('Source control is not connected. Check site\'s settings.'));
}
}
}
/**
* @throws Throwable
*/
public function disable(): void
{
if ($this->site->auto_deployment) {
try {
$this->site->disableAutoDeployment();
$this->site->refresh();
$this->toast()->success(__('Auto deployment has been disabled.'));
} catch (SourceControlIsNotConnected) {
$this->toast()->error(__('Source control is not connected. Check site\'s settings.'));
}
}
}
public function render(): View
{
return view('livewire.application.auto-deployment');
}
}

View File

@ -1,35 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Actions\Site\UpdateBranch;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ChangeBranch extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public string $branch;
public function mount(): void
{
$this->branch = $this->site->branch;
}
public function change(): void
{
app(UpdateBranch::class)->update($this->site, $this->all());
session()->flash('status', 'updating-branch');
}
public function render(): View
{
return view('livewire.application.change-branch');
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Exceptions\SourceControlIsNotConnected;
use App\Models\Site;
use App\Traits\HasToast;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class Deploy extends Component
{
use HasToast;
use RefreshComponentOnBroadcast;
public Site $site;
public function deploy(): void
{
try {
$this->site->deploy();
$this->toast()->success(__('Deployment started!'));
$this->dispatch('$refresh')->to(DeploymentsList::class);
$this->dispatch('$refresh')->to(DeploymentScript::class);
} catch (SourceControlIsNotConnected $e) {
session()->flash('toast.type', 'error');
session()->flash('toast.message', $e->getMessage());
$this->redirect(route('source-controls'));
}
}
public function render(): View
{
return view('livewire.application.deploy');
}
}

View File

@ -1,38 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Actions\Site\UpdateDeploymentScript;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class DeploymentScript extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public string $script;
public function mount(): void
{
$this->script = $this->site->deploymentScript->content;
}
public function save(): void
{
app(UpdateDeploymentScript::class)->update($this->site, $this->all());
session()->flash('status', 'script-updated');
$this->dispatch('$refresh')->to(Deploy::class);
$this->dispatch('$refresh')->to(AutoDeployment::class);
}
public function render(): View
{
return view('livewire.application.deployment-script');
}
}

View File

@ -1,34 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Models\Site;
use App\Traits\HasCustomPaginationView;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class DeploymentsList extends Component
{
use HasCustomPaginationView;
use RefreshComponentOnBroadcast;
public Site $site;
public string $logContent;
public function showLog(int $id): void
{
$deployment = $this->site->deployments()->findOrFail($id);
$this->logContent = $deployment->log->content;
$this->dispatch('open-modal', 'show-log');
}
public function render(): View
{
return view('livewire.application.deployments-list', [
'deployments' => $this->site->deployments()->latest()->simplePaginate(10),
]);
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Actions\Site\UpdateEnv;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class Env extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public string $env = 'Loading...';
public function loadEnv(): void
{
$this->env = $this->site->getEnv();
}
public function save(): void
{
app(UpdateEnv::class)->update($this->site, $this->all());
session()->flash('status', 'updating-env');
$this->dispatch('$refresh')->to(Deploy::class);
}
public function render(): View
{
return view('livewire.application.env');
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class LaravelApp extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public function render(): View
{
return view('livewire.application.laravel-app');
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class PhpApp extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public function render(): View
{
return view('livewire.application.php-app');
}
}

View File

@ -1,19 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Livewire\Component;
class PhpBlankApp extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public function render()
{
return view('livewire.application.php-blank-app');
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace App\Http\Livewire\Application;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class WordpressApp extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public function render(): View
{
return view('livewire.application.wordpress-app');
}
}

View File

@ -1,21 +0,0 @@
<?php
namespace App\Http\Livewire;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Cache;
use Livewire\Component;
class Broadcast extends Component
{
public function render(): View
{
$event = Cache::get('broadcast');
if ($event) {
Cache::forget('broadcast');
$this->dispatch('broadcast', $event);
}
return view('livewire.broadcast');
}
}

View File

@ -1,34 +0,0 @@
<?php
namespace App\Http\Livewire\Cronjobs;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class CreateCronjob extends Component
{
public Server $server;
public string $user = '';
public string $command;
public string $frequency = '';
public string $custom;
public function create(): void
{
app(\App\Actions\CronJob\CreateCronJob::class)->create($this->server, $this->all());
$this->dispatch('$refresh')->to(CronjobsList::class);
$this->dispatch('created');
}
public function render(): View
{
return view('livewire.cronjobs.create-cronjob');
}
}

View File

@ -1,35 +0,0 @@
<?php
namespace App\Http\Livewire\Cronjobs;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class CronjobsList extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public int $deleteId;
public function delete(): void
{
$cronjob = $this->server->cronJobs()->where('id', $this->deleteId)->firstOrFail();
$cronjob->removeFromServer();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.cronjobs.cronjobs-list', [
'cronjobs' => $this->server->cronJobs,
]);
}
}

View File

@ -1,67 +0,0 @@
<?php
namespace App\Http\Livewire\Databases;
use App\Models\Backup;
use App\Models\BackupFile;
use App\Models\Database;
use App\Models\Server;
use App\Traits\HasCustomPaginationView;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class DatabaseBackupFiles extends Component
{
use HasCustomPaginationView;
use RefreshComponentOnBroadcast;
public Server $server;
public Backup $backup;
public string $restoreId = '';
public string $restoreDatabaseId = '';
public int $deleteId;
public function backup(): void
{
$this->backup->run();
$this->refreshComponent([]);
}
public function restore(): void
{
/** @var BackupFile $file */
$file = BackupFile::query()->findOrFail($this->restoreId);
/** @var Database $database */
$database = Database::query()->findOrFail($this->restoreDatabaseId);
$file->restore($database);
$this->refreshComponent([]);
$this->dispatch('restored');
}
public function delete(): void
{
/** @var BackupFile $file */
$file = BackupFile::query()->findOrFail($this->deleteId);
$file->delete();
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.databases.database-backup-files', [
'files' => $this->backup->files()->orderByDesc('id')->simplePaginate(10),
]);
}
}

View File

@ -1,81 +0,0 @@
<?php
namespace App\Http\Livewire\Databases;
use App\Actions\Database\CreateBackup;
use App\Models\Backup;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Contracts\View\View;
use Livewire\Component;
use Livewire\WithPagination;
class DatabaseBackups extends Component
{
use RefreshComponentOnBroadcast;
use WithPagination;
public Server $server;
public int $deleteId;
public string $database = '';
public string $storage = '';
public string $interval = '';
public string $custom = '';
public int $keep = 10;
public ?Backup $backup = null;
protected ?Paginator $files = null;
public function create(): void
{
app(CreateBackup::class)->create('database', $this->server, $this->all());
$this->refreshComponent([]);
$this->dispatch('backup-created');
}
public function files(int $id): void
{
$backup = Backup::query()->findOrFail($id);
$this->backup = $backup;
$this->files = $backup->files()->orderByDesc('id')->simplePaginate(1);
$this->dispatch('show-files');
}
public function backup(): void
{
$this->backup?->run();
$this->files = $this->backup?->files()->orderByDesc('id')->simplePaginate();
$this->dispatch('backup-running');
}
public function delete(): void
{
/** @var Backup $backup */
$backup = Backup::query()->findOrFail($this->deleteId);
$backup->delete();
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.databases.database-backups', [
'backups' => $this->server->backups,
'databases' => $this->server->databases,
'files' => $this->files,
]);
}
}

View File

@ -1,66 +0,0 @@
<?php
namespace App\Http\Livewire\Databases;
use App\Actions\Database\CreateDatabase;
use App\Actions\Database\CreateDatabaseUser;
use App\Models\Database;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class DatabaseList extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public int $deleteId;
public string $name;
public bool $user;
public string $username;
public string $password;
public bool $remote = false;
public string $host = '%';
public function create(): void
{
$database = app(CreateDatabase::class)->create($this->server, $this->all());
if ($this->all()['user']) {
app(CreateDatabaseUser::class)->create($this->server, $this->all(), [$database->name]);
}
$this->refreshComponent([]);
$this->dispatch('database-created');
}
public function delete(): void
{
/** @var Database $database */
$database = Database::query()->findOrFail($this->deleteId);
$database->deleteFromServer();
$this->refreshComponent([]);
$this->dispatch('$refresh')->to(DatabaseUserList::class);
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.databases.database-list', [
'databases' => $this->server->databases,
]);
}
}

View File

@ -1,98 +0,0 @@
<?php
namespace App\Http\Livewire\Databases;
use App\Actions\Database\CreateDatabaseUser;
use App\Actions\Database\LinkUser;
use App\Models\DatabaseUser;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class DatabaseUserList extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public int $deleteId;
public string $username;
public string $password;
public bool $remote;
public string $host = '%';
public int $linkId;
public array $link = [];
public string $viewPassword = '';
public function create(): void
{
app(CreateDatabaseUser::class)->create($this->server, $this->all());
$this->refreshComponent([]);
$this->dispatch('database-user-created');
}
public function delete(): void
{
/** @var DatabaseUser $databaseUser */
$databaseUser = DatabaseUser::query()->findOrFail($this->deleteId);
$databaseUser->deleteFromServer();
$this->refreshComponent([]);
$this->dispatch('$refresh')->to(DatabaseList::class);
$this->dispatch('confirmed');
}
public function viewPassword(int $id): void
{
/** @var DatabaseUser $databaseUser */
$databaseUser = DatabaseUser::query()->findOrFail($id);
$this->viewPassword = $databaseUser->password;
$this->dispatch('open-modal', 'database-user-password');
}
public function showLink(int $id): void
{
/** @var DatabaseUser $databaseUser */
$databaseUser = DatabaseUser::query()->findOrFail($id);
$this->linkId = $id;
$this->link = $databaseUser->databases ?? [];
$this->dispatch('open-modal', 'link-database-user');
}
public function link(): void
{
/** @var DatabaseUser $databaseUser */
$databaseUser = DatabaseUser::query()->findOrFail($this->linkId);
app(LinkUser::class)->link($databaseUser, $this->link);
$this->refreshComponent([]);
$this->dispatch('linked');
}
public function render(): View
{
return view('livewire.databases.database-user-list', [
'databases' => $this->server->databases,
'databaseUsers' => $this->server->databaseUsers,
]);
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace App\Http\Livewire\Firewall;
use App\Actions\FirewallRule\CreateRule;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class CreateFirewallRule extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public string $type = 'allow';
public string $protocol = 'tcp';
public string $port;
public string $source = '0.0.0.0';
public string $mask = '';
public function create(): void
{
app(CreateRule::class)->create($this->server, $this->all());
$this->dispatch('$refresh')->to(FirewallRulesList::class);
$this->dispatch('created');
}
public function render(): View
{
return view('livewire.firewall.create-firewall-rule');
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Http\Livewire\Firewall;
use App\Models\FirewallRule;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class FirewallRulesList extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public int $deleteId;
public function delete(): void
{
/** @var FirewallRule $rule */
$rule = FirewallRule::query()->findOrFail($this->deleteId);
$rule->removeFromServer();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.firewall.firewall-rules-list', [
'rules' => $this->server->firewallRules,
]);
}
}

View File

@ -1,38 +0,0 @@
<?php
namespace App\Http\Livewire\NotificationChannels;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class AddChannel extends Component
{
public string $provider = '';
public string $label;
public string $webhook_url;
public string $email;
public string $bot_token;
public string $chat_id;
public function add(): void
{
app(\App\Actions\NotificationChannels\AddChannel::class)->add(
auth()->user(),
$this->all()
);
$this->dispatch('$refresh')->to(ChannelsList::class);
$this->dispatch('added');
}
public function render(): View
{
return view('livewire.notification-channels.add-channel');
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Http\Livewire\NotificationChannels;
use App\Models\NotificationChannel;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ChannelsList extends Component
{
use RefreshComponentOnBroadcast;
public int $deleteId;
protected $listeners = [
'$refresh',
];
public function delete(): void
{
$channel = NotificationChannel::query()->findOrFail($this->deleteId);
$channel->delete();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.notification-channels.channels-list', [
'channels' => NotificationChannel::query()->latest()->get(),
]);
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace App\Http\Livewire\Php;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class DefaultCli extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public function change(string $version): void
{
$this->server->php($version)->handler()->setDefaultCli();
$this->refreshComponent([]);
}
public function render(): View
{
return view('livewire.php.default-cli', [
'defaultPHP' => $this->server->defaultService('php'),
'phps' => $this->server->services()->where('type', 'php')->get(), //
]);
}
}

View File

@ -1,117 +0,0 @@
<?php
namespace App\Http\Livewire\Php;
use App\Actions\PHP\InstallNewPHP;
use App\Actions\PHP\InstallPHPExtension;
use App\Actions\PHP\UpdatePHPIni;
use App\Models\Server;
use App\Models\Service;
use App\SSHCommands\PHP\GetPHPIniCommand;
use App\Traits\RefreshComponentOnBroadcast;
use Exception;
use Illuminate\Contracts\View\View;
use Livewire\Component;
use Throwable;
class InstalledVersions extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public int $uninstallId;
public int $iniId;
public string $ini = 'Loading php.ini';
public ?int $extensionId = null;
public string $extension = '';
public function install(string $version): void
{
app(InstallNewPHP::class)->install($this->server, [
'version' => $version,
]);
$this->refreshComponent([]);
}
public function restart(int $id): void
{
/** @var Service $service */
$service = Service::query()->findOrFail($id);
$service->restart();
$this->refreshComponent([]);
}
public function uninstall(): void
{
/** @var Service $service */
$service = Service::query()->findOrFail($this->uninstallId);
$service->uninstall();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function loadIni(int $id): void
{
$this->iniId = $id;
$this->ini = 'Loading php.ini';
/** @var Service $service */
$service = Service::query()->findOrFail($this->iniId);
try {
$this->ini = $service->server->ssh()->exec(new GetPHPIniCommand($service->version));
} catch (Throwable) {
//
}
}
public function saveIni(): void
{
/** @var Service $service */
$service = Service::query()->findOrFail($this->iniId);
app(UpdatePHPIni::class)->update($service, $this->all()['ini']);
$this->refreshComponent([]);
session()->flash('status', 'ini-updated');
}
/**
* @throws Exception
*/
public function installExtension(): void
{
/** @var Service $service */
$service = Service::query()->findOrFail($this->extensionId);
app(InstallPHPExtension::class)->handle($service, [
'name' => $this->extension,
]);
session()->flash('status', 'started-installation');
}
public function render(): View
{
if ($this->extensionId) {
/** @var Service $php */
$php = Service::query()->findOrFail($this->extensionId);
$installedExtensions = $php->type_data['extensions'] ?? [];
}
return view('livewire.php.installed-versions', [
'phps' => $this->server->services()->where('type', 'php')->get(),
'installedExtensions' => $installedExtensions ?? [],
]);
}
}

View File

@ -1,14 +0,0 @@
<?php
namespace App\Http\Livewire\Profile;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class TwoFactorAuthentication extends Component
{
public function render(): View
{
return view('livewire.profile.two-factor-authentication');
}
}

View File

@ -1,32 +0,0 @@
<?php
namespace App\Http\Livewire\Profile;
use App\Actions\User\UpdateUserPassword;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class UpdatePassword extends Component
{
public string $current_password;
public string $password;
public string $password_confirmation;
public function update(): void
{
app(UpdateUserPassword::class)->update(auth()->user(), $this->all());
$this->current_password = '';
$this->password = '';
$this->password_confirmation = '';
session()->flash('status', 'password-updated');
}
public function render(): View
{
return view('livewire.profile.update-password');
}
}

View File

@ -1,54 +0,0 @@
<?php
namespace App\Http\Livewire\Profile;
use App\Actions\User\UpdateUserProfileInformation;
use App\Http\Livewire\UserDropdown;
use App\Models\User;
use Exception;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class UpdateProfileInformation extends Component
{
public string $name;
public string $email;
public string $timezone;
public function mount(): void
{
$this->name = auth()->user()->name;
$this->email = auth()->user()->email;
$this->timezone = auth()->user()->timezone;
}
/**
* @throws Exception
*/
public function submit(): void
{
app(UpdateUserProfileInformation::class)->update(auth()->user(), $this->all());
session()->flash('status', 'profile-updated');
$this->dispatch('$refresh')->to(UserDropdown::class);
}
public function sendVerificationEmail(): void
{
/** @var User $user */
$user = auth()->user();
if (! $user->hasVerifiedEmail()) {
$user->sendEmailVerificationNotification();
session()->flash('status', 'verification-link-sent');
}
}
public function render(): View
{
return view('livewire.profile.update-profile-information');
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Http\Livewire\Projects;
use App\Traits\HasToast;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class CreateProject extends Component
{
use HasToast;
use RefreshComponentOnBroadcast;
public bool $open = false;
public array $inputs = [];
public function create(): void
{
app(\App\Actions\Projects\CreateProject::class)
->create(auth()->user(), $this->inputs);
$this->dispatch('$refresh')->to(ProjectsList::class);
$this->dispatch('created');
}
public function render(): View
{
if (request()->query('create')) {
$this->open = true;
}
return view('livewire.projects.create-project');
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Http\Livewire\Projects;
use App\Actions\Projects\UpdateProject;
use App\Models\Project;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class EditProject extends Component
{
use RefreshComponentOnBroadcast;
public Project $project;
public array $inputs = [];
public function save(): void
{
app(UpdateProject::class)->update($this->project, $this->inputs);
$this->redirect(route('projects'));
}
public function mount(): void
{
$this->inputs = [
'name' => $this->project->name,
];
}
public function render(): View
{
return view('livewire.projects.edit-project');
}
}

View File

@ -1,42 +0,0 @@
<?php
namespace App\Http\Livewire\Projects;
use App\Actions\Projects\DeleteProject;
use App\Traits\HasToast;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Illuminate\Validation\ValidationException;
use Livewire\Component;
class ProjectsList extends Component
{
use HasToast;
use RefreshComponentOnBroadcast;
protected $listeners = [
'$refresh',
];
public int $deleteId;
public function delete(): void
{
try {
app(DeleteProject::class)->delete(auth()->user(), $this->deleteId);
$this->redirect(route('projects'));
return;
} catch (ValidationException $e) {
$this->toast()->error($e->getMessage());
}
}
public function render(): View
{
return view('livewire.projects.projects-list', [
'projects' => auth()->user()->projects()->orderByDesc('id')->get(),
]);
}
}

View File

@ -1,36 +0,0 @@
<?php
namespace App\Http\Livewire\Queues;
use App\Models\Site;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class CreateQueue extends Component
{
public Site $site;
public string $command;
public string $user = '';
public int $auto_start = 1;
public int $auto_restart = 1;
public int $numprocs;
public function create(): void
{
app(\App\Actions\Queue\CreateQueue::class)->create($this->site, $this->all());
$this->dispatch('$refresh')->to(QueuesList::class);
$this->dispatch('created');
}
public function render(): View
{
return view('livewire.queues.create-queue');
}
}

View File

@ -1,57 +0,0 @@
<?php
namespace App\Http\Livewire\Queues;
use App\Models\Queue;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class QueuesList extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public int $deleteId;
public function delete(): void
{
$queue = $this->site->queues()->findOrFail($this->deleteId);
$queue->remove();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function start(Queue $queue): void
{
$queue->start();
$this->refreshComponent([]);
}
public function restart(Queue $queue): void
{
$queue->restart();
$this->refreshComponent([]);
}
public function stop(Queue $queue): void
{
$queue->stop();
$this->refreshComponent([]);
}
public function render(): View
{
return view('livewire.queues.queues-list', [
'queues' => $this->site->queues,
]);
}
}

View File

@ -1,58 +0,0 @@
<?php
namespace App\Http\Livewire\ServerLogs;
use App\Models\Server;
use App\Models\Site;
use App\Traits\HasCustomPaginationView;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class LogsList extends Component
{
use HasCustomPaginationView;
use RefreshComponentOnBroadcast;
public ?int $count = null;
public Server $server;
public ?Site $site = null;
public string $logContent;
public function showLog(int $id): void
{
$log = $this->server->logs()->findOrFail($id);
$this->logContent = $log->content;
$this->dispatch('open-modal', 'show-log');
}
public function render(): View
{
if ($this->site) {
return $this->renderSite();
}
if ($this->count) {
$logs = $this->server->logs()->latest()->take(10)->get();
} else {
$logs = $this->server->logs()->latest()->simplePaginate(10);
}
return view('livewire.server-logs.logs-list', compact('logs'));
}
private function renderSite(): View
{
if ($this->count) {
$logs = $this->site->logs()->latest()->take(10)->get();
} else {
$logs = $this->site->logs()->latest()->simplePaginate(10);
}
return view('livewire.server-logs.logs-list', compact('logs'));
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace App\Http\Livewire\ServerProviders;
use App\Actions\ServerProvider\CreateServerProvider;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ConnectProvider extends Component
{
public string $provider = '';
public string $name;
public string $token;
public string $key;
public string $secret;
public function connect(): void
{
app(CreateServerProvider::class)->create(auth()->user(), $this->all());
$this->dispatch('$refresh')->to(ProvidersList::class);
$this->dispatch('connected');
}
public function render(): View
{
if (request()->query('provider')) {
$this->provider = request()->query('provider');
}
return view('livewire.server-providers.connect-provider', [
'open' => ! is_null(request()->query('provider')),
]);
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Http\Livewire\ServerProviders;
use App\Models\ServerProvider;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ProvidersList extends Component
{
use RefreshComponentOnBroadcast;
public int $deleteId;
protected $listeners = [
'$refresh',
];
public function delete(): void
{
$provider = ServerProvider::query()->findOrFail($this->deleteId);
$provider->delete();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.server-providers.providers-list', [
'providers' => ServerProvider::query()->latest()->get(),
]);
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace App\Http\Livewire\ServerSettings;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class CheckConnection extends Component
{
public Server $server;
public function check(): void
{
$this->server->checkConnection();
session()->flash('status', 'checking-connection');
}
public function render(): View
{
return view('livewire.server-settings.check-connection');
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace App\Http\Livewire\ServerSettings;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class EditServer extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public string $name;
public string $ip;
public string $port;
public function mount(): void
{
$this->name = $this->server->name;
$this->ip = $this->server->ip;
$this->port = $this->server->port;
}
public function update(): void
{
app(\App\Actions\Server\EditServer::class)->edit($this->server, $this->all());
session()->flash('status', 'server-updated');
}
public function render(): View
{
return view('livewire.server-settings.edit-server');
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace App\Http\Livewire\ServerSettings;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class RebootServer extends Component
{
public Server $server;
public function reboot(): void
{
$this->server->reboot();
session()->flash('status', 'rebooting-server');
}
public function render(): View
{
return view('livewire.server-settings.reboot-server');
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace App\Http\Livewire\ServerSettings;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ServerDetails extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public function render(): View
{
return view('livewire.server-settings.server-details');
}
}

View File

@ -1,33 +0,0 @@
<?php
namespace App\Http\Livewire\ServerSshKeys;
use App\Models\Server;
use App\Models\SshKey;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class AddExistingKey extends Component
{
public Server $server;
public string $key_id = '';
public function add(): void
{
$key = SshKey::query()->findOrFail($this->all()['key_id']);
$key->deployTo($this->server);
$this->dispatch('$refresh')->to(ServerKeysList::class);
$this->dispatch('added');
}
public function render(): View
{
return view('livewire.server-ssh-keys.add-existing-key', [
'keys' => SshKey::all(),
]);
}
}

View File

@ -1,36 +0,0 @@
<?php
namespace App\Http\Livewire\ServerSshKeys;
use App\Actions\SshKey\CreateSshKey;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class AddNewKey extends Component
{
public Server $server;
public string $name;
public string $public_key;
public function add(): void
{
$key = app(CreateSshKey::class)->create(
auth()->user(),
$this->all()
);
$key->deployTo($this->server);
$this->dispatch('$refresh')->to(ServerKeysList::class);
$this->dispatch('added');
}
public function render(): View
{
return view('livewire.server-ssh-keys.add-new-key');
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace App\Http\Livewire\ServerSshKeys;
use App\Models\Server;
use App\Models\SshKey;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ServerKeysList extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public int $deleteId;
protected $listeners = [
'$refresh',
];
public function delete(): void
{
$key = SshKey::query()->findOrFail($this->deleteId);
$key->deleteFrom($this->server);
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.server-ssh-keys.server-keys-list', [
'keys' => $this->server->sshKeys,
]);
}
}

View File

@ -1,64 +0,0 @@
<?php
namespace App\Http\Livewire\Servers;
use App\Enums\Database;
use App\Enums\OperatingSystem;
use App\Enums\ServerType;
use App\Enums\Webserver;
use App\Models\ServerProvider;
use Illuminate\Contracts\View\View;
use Livewire\Component;
use Throwable;
class CreateServer extends Component
{
public string $provider = 'custom';
public string $server_provider = '';
public string $type = ServerType::REGULAR;
public string $name;
public string $ip;
public string $port;
public string $os = OperatingSystem::UBUNTU22;
public string $webserver = Webserver::NGINX;
public string $database = Database::MYSQL80;
public string $php = '8.2';
public string $plan = '';
public string $region = '';
/**
* @throws Throwable
*/
public function submit(): void
{
$server = app(\App\Actions\Server\CreateServer::class)->create(
auth()->user(),
$this->all()
);
$this->redirect(route('servers.show', ['server' => $server]));
}
public function render(): View
{
$serverProviders = ServerProvider::query()->where('provider', $this->provider)->get();
return view(
'livewire.servers.create-server',
compact([
'serverProviders',
])
);
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace App\Http\Livewire\Servers;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class DeleteServer extends Component
{
public Server $server;
public function mount(Server $server): void
{
$this->server = $server;
}
public function delete(): void
{
$this->server->delete();
$this->redirect(route('servers'));
}
public function render(): View
{
return view('livewire.servers.delete-server');
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace App\Http\Livewire\Servers;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ServerStatus extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public function render(): View
{
return view('livewire.servers.server-status');
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace App\Http\Livewire\Servers;
use App\Models\User;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ServersList extends Component
{
use RefreshComponentOnBroadcast;
public function render(): View
{
/** @var User $user */
$user = auth()->user();
$servers = $user->currentProject->servers()->orderByDesc('created_at')->get();
return view('livewire.servers.servers-list', [
'servers' => $servers,
]);
}
}

View File

@ -1,31 +0,0 @@
<?php
namespace App\Http\Livewire\Servers;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ShowServer extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public function refreshComponent(array $data): void
{
if (isset($data['type']) && $data['type'] == 'install-server-finished') {
$this->redirect(route('servers.show', ['server' => $this->server]));
return;
}
$this->dispatch('refreshComponent');
}
public function render(): View
{
return view('livewire.servers.show-server');
}
}

View File

@ -1,31 +0,0 @@
<?php
namespace App\Http\Livewire\Services;
use App\Actions\Service\InstallPHPMyAdmin as InstallPHPMyAdminAction;
use App\Models\Server;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class InstallPHPMyAdmin extends Component
{
public Server $server;
public string $allowed_ip;
public string $port = '5433';
public function install(): void
{
app(InstallPHPMyAdminAction::class)->install($this->server, $this->all());
$this->dispatch('started');
$this->dispatch('$refresh')->to(ServicesList::class);
}
public function render(): View
{
return view('livewire.services.install-phpmyadmin');
}
}

View File

@ -1,63 +0,0 @@
<?php
namespace App\Http\Livewire\Services;
use App\Models\Server;
use App\Models\Service;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ServicesList extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public function stop(int $id): void
{
/** @var Service $service */
$service = $this->server->services()->where('id', $id)->firstOrFail();
$service->stop();
$this->refreshComponent([]);
}
public function start(int $id): void
{
/** @var Service $service */
$service = $this->server->services()->where('id', $id)->firstOrFail();
$service->start();
$this->refreshComponent([]);
}
public function restart(int $id): void
{
/** @var Service $service */
$service = $this->server->services()->where('id', $id)->firstOrFail();
$service->restart();
$this->refreshComponent([]);
}
public function uninstall(int $id): void
{
/** @var Service $service */
$service = $this->server->services()->where('id', $id)->firstOrFail();
$service->uninstall();
$this->refreshComponent([]);
}
public function render(): View
{
return view('livewire.services.services-list', [
'services' => $this->server->services,
]);
}
}

View File

@ -1,41 +0,0 @@
<?php
namespace App\Http\Livewire\Sites;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ChangePhpVersion extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public string $version;
public function mount(Site $site): void
{
$this->version = $site->php_version;
}
public function change(): void
{
$this->site->changePHPVersion($this->version);
session()->flash('status', 'changing-php-version');
}
public function refreshComponent(array $data): void
{
if (isset($data['type'])) {
session()->flash('status', $data['type']);
}
}
public function render(): View
{
return view('livewire.sites.change-php-version');
}
}

View File

@ -1,47 +0,0 @@
<?php
namespace App\Http\Livewire\Sites;
use App\Exceptions\SourceControlIsNotConnected;
use App\Models\Server;
use App\Models\SourceControl;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class CreateSite extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public array $inputs = [
'type' => '',
'web_directory' => 'public',
'source_control' => '',
'php_version' => '',
];
/**
* @throws SourceControlIsNotConnected
*/
public function create(): void
{
$site = app(\App\Actions\Site\CreateSite::class)->create(
$this->server,
$this->inputs
);
$this->redirect(route('servers.sites.show', [
'server' => $site->server,
'site' => $site,
]));
}
public function render(): View
{
return view('livewire.sites.create-site', [
'sourceControls' => SourceControl::all(),
]);
}
}

View File

@ -1,27 +0,0 @@
<?php
namespace App\Http\Livewire\Sites;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class DeleteSite extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public function delete(): void
{
$this->site->remove();
$this->redirect(route('servers.sites', ['server' => $this->site->server]));
}
public function render(): View
{
return view('livewire.sites.delete-site');
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace App\Http\Livewire\Sites;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ShowSite extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public function render(): View
{
return view('livewire.sites.show-site');
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace App\Http\Livewire\Sites;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class SiteStatus extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public function render(): View
{
return view('livewire.sites.site-status');
}
}

View File

@ -1,38 +0,0 @@
<?php
namespace App\Http\Livewire\Sites;
use App\Models\Server;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class SitesList extends Component
{
use RefreshComponentOnBroadcast;
public Server $server;
public function refreshComponent(array $data): void
{
if (isset($data['type']) && $data['type'] == 'install-site-finished') {
$this->redirect(
route('servers.sites.show', [
'server' => $this->server,
'site' => $data['data']['site']['id'],
])
);
return;
}
$this->dispatch('refreshComponent');
}
public function render(): View
{
return view('livewire.sites.sites-list', [
'sites' => $this->server->sites()->latest()->get(),
]);
}
}

View File

@ -1,33 +0,0 @@
<?php
namespace App\Http\Livewire\Sites;
use App\Actions\Site\UpdateSourceControl;
use App\Models\Site;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class UpdateSourceControlProvider extends Component
{
public Site $site;
public $source_control = null;
public function update(): void
{
app(UpdateSourceControl::class)->update($this->site, $this->all());
$this->resetErrorBag();
session()->flash('status', 'source-control-updated');
}
public function render(): View
{
if (! $this->source_control) {
$this->source_control = $this->site->source_control_id;
}
return view('livewire.sites.update-source-control-provider');
}
}

View File

@ -1,41 +0,0 @@
<?php
namespace App\Http\Livewire\Sites;
use App\Models\Site;
use App\Traits\HasToast;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
use Throwable;
class UpdateVHost extends Component
{
use HasToast;
use RefreshComponentOnBroadcast;
public Site $site;
public string $vHost = 'Loading...';
public function loadVHost(): void
{
$this->vHost = $this->site->server->webserver()->handler()->getVHost($this->site);
}
public function update(): void
{
try {
$this->site->server->webserver()->handler()->updateVHost($this->site, false, $this->vHost);
$this->toast()->success('VHost updated successfully!');
} catch (Throwable $e) {
$this->toast()->error($e->getMessage());
}
}
public function render(): View
{
return view('livewire.sites.update-v-host');
}
}

View File

@ -1,38 +0,0 @@
<?php
namespace App\Http\Livewire\SourceControls;
use App\Actions\SourceControl\ConnectSourceControl;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class Connect extends Component
{
public string $provider = '';
public string $name;
public string $token;
public string $url;
public function connect(): void
{
app(ConnectSourceControl::class)->connect($this->all());
$this->dispatch('$refresh')->to(SourceControlsList::class);
$this->dispatch('connected');
}
public function render(): View
{
if (request()->query('provider')) {
$this->provider = request()->query('provider');
}
return view('livewire.source-controls.connect', [
'open' => ! is_null(request()->query('provider')),
]);
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Http\Livewire\SourceControls;
use App\Models\SourceControl;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class SourceControlsList extends Component
{
use RefreshComponentOnBroadcast;
public int $deleteId;
protected $listeners = [
'$refresh',
];
public function delete(): void
{
$provider = SourceControl::query()->findOrFail($this->deleteId);
$provider->delete();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.source-controls.source-controls-list', [
'sourceControls' => SourceControl::query()->latest()->get(),
]);
}
}

View File

@ -1,31 +0,0 @@
<?php
namespace App\Http\Livewire\SshKeys;
use App\Actions\SshKey\CreateSshKey;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class AddKey extends Component
{
public string $name;
public string $public_key;
public function add(): void
{
app(CreateSshKey::class)->create(
auth()->user(),
$this->all()
);
$this->dispatch('$refresh')->to(KeysList::class);
$this->dispatch('added');
}
public function render(): View
{
return view('livewire.ssh-keys.add-key');
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Http\Livewire\SshKeys;
use App\Models\SshKey;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class KeysList extends Component
{
use RefreshComponentOnBroadcast;
public int $deleteId;
protected $listeners = [
'$refresh',
];
public function delete(): void
{
$key = SshKey::query()->findOrFail($this->deleteId);
$key->delete();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.ssh-keys.keys-list', [
'keys' => SshKey::query()->latest()->get(),
]);
}
}

View File

@ -1,35 +0,0 @@
<?php
namespace App\Http\Livewire\Ssl;
use App\Models\Site;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class CreateSsl extends Component
{
use RefreshComponentOnBroadcast;
public Site $site;
public string $type = '';
public string $certificate;
public string $private;
public function create(): void
{
app(\App\Actions\SSL\CreateSSL::class)->create($this->site, $this->all());
$this->dispatch('$refresh')->to(SslsList::class);
$this->dispatch('created');
}
public function render(): View
{
return view('livewire.ssl.create-ssl');
}
}

View File

@ -1,46 +0,0 @@
<?php
namespace App\Http\Livewire\Ssl;
use App\Models\Site;
use App\Traits\HasToast;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class SslsList extends Component
{
use HasToast;
use RefreshComponentOnBroadcast;
public Site $site;
public int $deleteId;
public function delete(): void
{
$ssl = $this->site->ssls()->where('id', $this->deleteId)->firstOrFail();
$ssl->remove();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function refreshComponent(array $data): void
{
if (isset($data['type']) && $data['type'] == 'deploy-ssl-failed') {
$this->toast()->error(__('SSL creation failed!'));
}
$this->dispatch('refreshComponent');
}
public function render(): View
{
return view('livewire.ssl.ssls-list', [
'ssls' => $this->site->ssls,
]);
}
}

View File

@ -1,44 +0,0 @@
<?php
namespace App\Http\Livewire\StorageProviders;
use App\Actions\StorageProvider\CreateStorageProvider;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ConnectProvider extends Component
{
public string $provider = '';
public string $name;
public string $token;
public string $host;
public string $port;
public string $path = '/';
public string $username;
public string $password;
public int $ssl = 1;
public int $passive = 0;
public function connect(): void
{
app(CreateStorageProvider::class)->create(auth()->user(), $this->all());
$this->dispatch('$refresh')->to(ProvidersList::class);
$this->dispatch('connected');
}
public function render(): View
{
return view('livewire.storage-providers.connect-provider');
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Http\Livewire\StorageProviders;
use App\Models\StorageProvider;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ProvidersList extends Component
{
use RefreshComponentOnBroadcast;
public int $deleteId;
protected $listeners = [
'$refresh',
];
public function delete(): void
{
$provider = StorageProvider::query()->findOrFail($this->deleteId);
$provider->delete();
$this->refreshComponent([]);
$this->dispatch('confirmed');
}
public function render(): View
{
return view('livewire.storage-providers.providers-list', [
'providers' => StorageProvider::query()->latest()->get(),
]);
}
}

View File

@ -1,18 +0,0 @@
<?php
namespace App\Http\Livewire;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class UserDropdown extends Component
{
protected $listeners = [
'$refresh',
];
public function render(): View
{
return view('livewire.user-dropdown');
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Middleware;
use App\Exceptions\SSHCommandError;
use App\Exceptions\SSHConnectionError;
use App\Facades\Toast;
use Closure;
use Illuminate\Http\Request;
class HandleSSHErrors
{
public function handle(Request $request, Closure $next)
{
$res = $next($request);
if ($res->exception) {
if ($res->exception instanceof SSHConnectionError || $res->exception instanceof SSHCommandError) {
Toast::error($res->exception->getMessage());
if ($request->hasHeader('HX-Request')) {
return htmx()->back();
}
return back();
}
}
return $res;
}
}

View File

@ -1,85 +0,0 @@
<?php
namespace App\Http\Requests\Auth;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class LoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
];
}
/**
* Attempt to authenticate the request's credentials.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function authenticate(): void
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
/**
* Ensure the login request is not rate limited.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function ensureIsNotRateLimited(): void
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
/**
* Get the rate limiting throttle key for the request.
*/
public function throttleKey(): string
{
return Str::transliterate(Str::lower($this->input('email')).'|'.$this->ip());
}
}

View File

@ -1,23 +0,0 @@
<?php
namespace App\Http\Requests;
use App\Models\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class ProfileUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'name' => ['string', 'max:255'],
'email' => ['email', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)],
];
}
}