diff --git a/app/Actions/CoolifyTask/PrepareCoolifyTask.php b/app/Actions/CoolifyTask/PrepareCoolifyTask.php index 263cd329e..3b2f70014 100644 --- a/app/Actions/CoolifyTask/PrepareCoolifyTask.php +++ b/app/Actions/CoolifyTask/PrepareCoolifyTask.php @@ -15,6 +15,7 @@ class PrepareCoolifyTask { protected Activity $activity; protected CoolifyTaskArgs $remoteProcessArgs; + public function __construct(CoolifyTaskArgs $remoteProcessArgs) { $this->remoteProcessArgs = $remoteProcessArgs; diff --git a/app/Actions/CoolifyTask/RunRemoteProcess.php b/app/Actions/CoolifyTask/RunRemoteProcess.php index 2a9fc63a0..0a7892f98 100644 --- a/app/Actions/CoolifyTask/RunRemoteProcess.php +++ b/app/Actions/CoolifyTask/RunRemoteProcess.php @@ -49,6 +49,28 @@ public function __construct(Activity $activity, bool $hide_from_output = false, $this->ignore_errors = $ignore_errors; } + public static function decodeOutput(?Activity $activity = null): string + { + if (is_null($activity)) { + return ''; + } + + try { + $decoded = json_decode( + data_get($activity, 'description'), + associative: true, + flags: JSON_THROW_ON_ERROR + ); + } catch (\JsonException $exception) { + return ''; + } + + return collect($decoded) + ->sortBy(fn($i) => $i['order']) + ->map(fn($i) => $i['output']) + ->implode(""); + } + public function __invoke(): ProcessResult { $this->time_start = hrtime(true); @@ -83,15 +105,6 @@ public function __invoke(): ProcessResult return $processResult; } - protected function getLatestCounter(): int - { - $description = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR); - if ($description === null || count($description) === 0) { - return 1; - } - return end($description)['order'] + 1; - } - protected function getCommand(): string { $user = $this->activity->getExtraProperty('user'); @@ -120,6 +133,13 @@ protected function handleOutput(string $type, string $output) } } + protected function elapsedTime(): int + { + $timeMs = (hrtime(true) - $this->time_start) / 1_000_000; + + return intval($timeMs); + } + public function encodeOutput($type, $output) { $outputStack = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR); @@ -135,26 +155,13 @@ public function encodeOutput($type, $output) return json_encode($outputStack, flags: JSON_THROW_ON_ERROR); } - public static function decodeOutput(?Activity $activity = null): string + protected function getLatestCounter(): int { - if (is_null($activity)) { - return ''; + $description = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR); + if ($description === null || count($description) === 0) { + return 1; } - - try { - $decoded = json_decode( - data_get($activity, 'description'), - associative: true, - flags: JSON_THROW_ON_ERROR - ); - } catch (\JsonException $exception) { - return ''; - } - - return collect($decoded) - ->sortBy(fn ($i) => $i['order']) - ->map(fn ($i) => $i['output']) - ->implode(""); + return end($description)['order'] + 1; } /** @@ -171,11 +178,4 @@ protected function isAfterLastThrottle() return ($this->current_time - $this->throttle_interval_ms) > $this->last_write_at; } - - protected function elapsedTime(): int - { - $timeMs = (hrtime(true) - $this->time_start) / 1_000_000; - - return intval($timeMs); - } } diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index 71d1132d3..b3e7dce5f 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -3,15 +3,14 @@ namespace App\Actions\Database; use App\Models\Server; -use App\Models\StandaloneDocker; -use App\Models\Team; use App\Models\StandalonePostgresql; -use Symfony\Component\Yaml\Yaml; use Illuminate\Support\Str; +use Symfony\Component\Yaml\Yaml; class StartPostgresql { public $database; + public function __invoke(Server $server, StandalonePostgresql $database) { $this->database = $database; @@ -83,28 +82,7 @@ public function __invoke(Server $server, StandalonePostgresql $database) ], $server); return $activity; } - private function generate_environment_variables() - { - $environment_variables = collect(); - ray('Generate Environment Variables')->green(); - ray($this->database->runtime_environment_variables)->green(); - foreach ($this->database->runtime_environment_variables as $env) { - $environment_variables->push("$env->key=$env->value"); - } - if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_USER'))->isEmpty()) { - $environment_variables->push("POSTGRES_USER={$this->database->postgres_user}"); - } - - if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_PASSWORD'))->isEmpty()) { - $environment_variables->push("POSTGRES_PASSWORD={$this->database->postgres_password}"); - } - - if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_DB'))->isEmpty()) { - $environment_variables->push("POSTGRES_DB={$this->database->postgres_db}"); - } - return $environment_variables->all(); - } private function generate_local_persistent_volumes() { $local_persistent_volumes = []; @@ -114,6 +92,7 @@ private function generate_local_persistent_volumes() } return $local_persistent_volumes; } + private function generate_local_persistent_volumes_only_volume_names() { $local_persistent_volumes_names = []; @@ -129,4 +108,27 @@ private function generate_local_persistent_volumes_only_volume_names() } return $local_persistent_volumes_names; } + + private function generate_environment_variables() + { + $environment_variables = collect(); + ray('Generate Environment Variables')->green(); + ray($this->database->runtime_environment_variables)->green(); + foreach ($this->database->runtime_environment_variables as $env) { + $environment_variables->push("$env->key=$env->value"); + } + + if ($environment_variables->filter(fn($env) => Str::of($env)->contains('POSTGRES_USER'))->isEmpty()) { + $environment_variables->push("POSTGRES_USER={$this->database->postgres_user}"); + } + + if ($environment_variables->filter(fn($env) => Str::of($env)->contains('POSTGRES_PASSWORD'))->isEmpty()) { + $environment_variables->push("POSTGRES_PASSWORD={$this->database->postgres_password}"); + } + + if ($environment_variables->filter(fn($env) => Str::of($env)->contains('POSTGRES_DB'))->isEmpty()) { + $environment_variables->push("POSTGRES_DB={$this->database->postgres_db}"); + } + return $environment_variables->all(); + } } diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php index 71dbcf28f..77ae73fce 100644 --- a/app/Actions/Fortify/CreateNewUser.php +++ b/app/Actions/Fortify/CreateNewUser.php @@ -3,11 +3,8 @@ namespace App\Actions\Fortify; use App\Models\InstanceSettings; -use App\Models\Team; use App\Models\User; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; -use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; use Laravel\Fortify\Contracts\CreatesNewUsers; @@ -19,7 +16,7 @@ class CreateNewUser implements CreatesNewUsers /** * Validate and create a newly registered user. * - * @param array $input + * @param array $input */ public function create(array $input): User { diff --git a/app/Actions/Fortify/ResetUserPassword.php b/app/Actions/Fortify/ResetUserPassword.php index 7a57c5037..58d99b1b2 100644 --- a/app/Actions/Fortify/ResetUserPassword.php +++ b/app/Actions/Fortify/ResetUserPassword.php @@ -14,7 +14,7 @@ class ResetUserPassword implements ResetsUserPasswords /** * Validate and reset the user's forgotten password. * - * @param array $input + * @param array $input */ public function reset(User $user, array $input): void { diff --git a/app/Actions/Fortify/UpdateUserPassword.php b/app/Actions/Fortify/UpdateUserPassword.php index 700563905..5ebf31875 100644 --- a/app/Actions/Fortify/UpdateUserPassword.php +++ b/app/Actions/Fortify/UpdateUserPassword.php @@ -14,7 +14,7 @@ class UpdateUserPassword implements UpdatesUserPasswords /** * Validate and update the user's password. * - * @param array $input + * @param array $input */ public function update(User $user, array $input): void { diff --git a/app/Actions/Fortify/UpdateUserProfileInformation.php b/app/Actions/Fortify/UpdateUserProfileInformation.php index 0930ddf38..c8f2cce59 100644 --- a/app/Actions/Fortify/UpdateUserProfileInformation.php +++ b/app/Actions/Fortify/UpdateUserProfileInformation.php @@ -13,7 +13,7 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation /** * Validate and update the given user's profile information. * - * @param array $input + * @param array $input */ public function update(User $user, array $input): void { @@ -43,7 +43,7 @@ public function update(User $user, array $input): void /** * Update the given verified user's profile information. * - * @param array $input + * @param array $input */ protected function updateVerifiedUser(User $user, array $input): void { diff --git a/app/Actions/Proxy/CheckConfigurationSync.php b/app/Actions/Proxy/CheckConfigurationSync.php index 3648aa388..af7804cb7 100644 --- a/app/Actions/Proxy/CheckConfigurationSync.php +++ b/app/Actions/Proxy/CheckConfigurationSync.php @@ -2,8 +2,6 @@ namespace App\Actions\Proxy; -use App\Actions\Proxy\SaveConfigurationSync; -use App\Enums\ProxyTypes; use App\Models\Server; use Illuminate\Support\Str; @@ -25,4 +23,4 @@ public function __invoke(Server $server, bool $reset = false) return $proxy_configuration; } -} \ No newline at end of file +} diff --git a/app/Actions/Proxy/StartProxy.php b/app/Actions/Proxy/StartProxy.php index cea5a2166..b9d9ab02b 100644 --- a/app/Actions/Proxy/StartProxy.php +++ b/app/Actions/Proxy/StartProxy.php @@ -2,12 +2,11 @@ namespace App\Actions\Proxy; -use App\Actions\Proxy\CheckConfigurationSync; use App\Enums\ProxyStatus; use App\Enums\ProxyTypes; use App\Models\Server; -use Spatie\Activitylog\Models\Activity; use Illuminate\Support\Str; +use Spatie\Activitylog\Models\Activity; class StartProxy { @@ -54,4 +53,4 @@ public function __invoke(Server $server): Activity return $activity; } -} \ No newline at end of file +} diff --git a/app/Actions/Server/UpdateCoolify.php b/app/Actions/Server/UpdateCoolify.php index 71231cd36..8b5644a1d 100644 --- a/app/Actions/Server/UpdateCoolify.php +++ b/app/Actions/Server/UpdateCoolify.php @@ -23,7 +23,7 @@ public function __invoke(bool $force) $this->server = Server::where('name', $localhost_name)->firstOrFail(); $this->latest_version = get_latest_version_of_coolify(); $this->current_version = config('version'); - ray('latest version:' . $this->latest_version . " current version: " . $this->current_version . ' force: ' . $force); + ray('latest version:' . $this->latest_version . " current version: " . $this->current_version . ' force: ' . $force); if ($settings->next_channel) { ray('next channel enabled'); $this->latest_version = 'next'; @@ -49,6 +49,7 @@ public function __invoke(bool $force) return; } } + private function update() { if (isDev()) { diff --git a/app/Console/Commands/Init.php b/app/Console/Commands/Init.php index 32ff31827..ae682e682 100644 --- a/app/Console/Commands/Init.php +++ b/app/Console/Commands/Init.php @@ -10,10 +10,12 @@ class Init extends Command { protected $signature = 'app:init'; protected $description = 'Cleanup instance related stuffs'; + public function handle() { $this->cleanup_in_progress_application_deployments(); } + private function cleanup_in_progress_application_deployments() { // Cleanup any failed deployments diff --git a/app/Console/Commands/NotifyDemo.php b/app/Console/Commands/NotifyDemo.php index 1d5906bd0..37b84d489 100644 --- a/app/Console/Commands/NotifyDemo.php +++ b/app/Console/Commands/NotifyDemo.php @@ -64,7 +64,8 @@ private function showHelp() - HTML); + HTML + ); ask(<<<'HTML'
diff --git a/app/Console/Commands/SyncBunny.php b/app/Console/Commands/SyncBunny.php index dec92dd6e..131d20130 100644 --- a/app/Console/Commands/SyncBunny.php +++ b/app/Console/Commands/SyncBunny.php @@ -4,8 +4,8 @@ use Illuminate\Console\Command; use Illuminate\Http\Client\PendingRequest; -use Illuminate\Support\Facades\Http; use Illuminate\Http\Client\Pool; +use Illuminate\Support\Facades\Http; class SyncBunny extends Command { @@ -64,7 +64,7 @@ public function handle() ]); }); try { - Http::pool(fn (Pool $pool) => [ + Http::pool(fn(Pool $pool) => [ $pool->storage(file: "$parent_dir/$compose_file")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file"), $pool->storage(file: "$parent_dir/$compose_file_prod")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file_prod"), $pool->storage(file: "$parent_dir/$production_env")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$production_env"), @@ -73,7 +73,7 @@ public function handle() $pool->storage(file: "$parent_dir/$versions")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$versions"), ]); ray("{$bunny_cdn}/{$bunny_cdn_path}"); - Http::pool(fn (Pool $pool) => [ + Http::pool(fn(Pool $pool) => [ $pool->purge("$bunny_cdn/$bunny_cdn_path/$compose_file"), $pool->purge("$bunny_cdn/$bunny_cdn_path/$compose_file_prod"), $pool->purge("$bunny_cdn/$bunny_cdn_path/$production_env"), diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 8acfc53c8..0714a5d75 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,12 +2,12 @@ namespace App\Console; -use App\Jobs\InstanceApplicationsStatusJob; use App\Jobs\CheckResaleLicenseJob; +use App\Jobs\CheckResaleLicenseKeys; +use App\Jobs\DockerCleanupJob; +use App\Jobs\InstanceApplicationsStatusJob; use App\Jobs\InstanceAutoUpdateJob; use App\Jobs\ProxyCheckJob; -use App\Jobs\DockerCleanupJob; -use App\Jobs\CheckResaleLicenseKeys; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -31,6 +31,7 @@ protected function schedule(Schedule $schedule): void $schedule->job(new InstanceAutoUpdateJob)->everyTenMinutes(); } } + protected function commands(): void { $this->load(__DIR__ . '/Commands'); diff --git a/app/Data/CoolifyTaskArgs.php b/app/Data/CoolifyTaskArgs.php index 1b30126f0..d451faa00 100644 --- a/app/Data/CoolifyTaskArgs.php +++ b/app/Data/CoolifyTaskArgs.php @@ -22,6 +22,7 @@ public function __construct( public ?Model $model = null, public string $status = ProcessStatus::QUEUED->value, public bool $ignore_errors = false, - ) { + ) + { } } diff --git a/app/Data/ServerMetadata.php b/app/Data/ServerMetadata.php index b96efa622..18f734ce4 100644 --- a/app/Data/ServerMetadata.php +++ b/app/Data/ServerMetadata.php @@ -9,8 +9,9 @@ class ServerMetadata extends Data { public function __construct( - public ?ProxyTypes $type, + public ?ProxyTypes $type, public ?ProxyStatus $status - ) { + ) + { } } diff --git a/app/Enums/ProxyTypes.php b/app/Enums/ProxyTypes.php index e94792188..dfbf65c64 100644 --- a/app/Enums/ProxyTypes.php +++ b/app/Enums/ProxyTypes.php @@ -8,6 +8,7 @@ enum ProxyTypes: string case NGINX = 'NGINX'; case CADDY = 'CADDY'; } + enum ProxyStatus: string { case EXITED = 'exited'; diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 3fc20bd25..9d9dabab6 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -4,13 +4,12 @@ use App\Models\InstanceSettings; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; -use Throwable; use Sentry\Laravel\Integration; +use Throwable; class Handler extends ExceptionHandler { - private InstanceSettings $settings; /** * A list of exception types with their corresponding custom log levels. * @@ -19,7 +18,6 @@ class Handler extends ExceptionHandler protected $levels = [ // ]; - /** * A list of the exception types that are not reported. * @@ -28,7 +26,6 @@ class Handler extends ExceptionHandler protected $dontReport = [ // ]; - /** * A list of the inputs that are never flashed to the session on validation exceptions. * @@ -39,6 +36,7 @@ class Handler extends ExceptionHandler 'password', 'password_confirmation', ]; + private InstanceSettings $settings; /** * Register the exception handling callbacks for the application. diff --git a/app/Http/Controllers/ApplicationController.php b/app/Http/Controllers/ApplicationController.php index b6685276f..3eb638426 100644 --- a/app/Http/Controllers/ApplicationController.php +++ b/app/Http/Controllers/ApplicationController.php @@ -5,12 +5,11 @@ use App\Models\ApplicationDeploymentQueue; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Validation\ValidatesRequests; -use Illuminate\Http\Request; -use Spatie\Activitylog\Models\Activity; class ApplicationController extends Controller { use AuthorizesRequests, ValidatesRequests; + public function configuration() { $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); @@ -28,6 +27,7 @@ public function configuration() ray($application->persistentStorages()->get()); return view('project.application.configuration', ['application' => $application]); } + public function deployments() { $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index a37672983..0c4838a97 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -2,17 +2,15 @@ namespace App\Http\Controllers; -use App\Http\Livewire\Team\Invitations; use App\Models\InstanceSettings; use App\Models\Project; +use App\Models\S3Storage; use App\Models\Server; use App\Models\TeamInvitation; use App\Models\User; -use App\Models\S3Storage; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; -use Illuminate\Support\Facades\DB; class Controller extends BaseController { @@ -27,6 +25,7 @@ public function subscription() 'settings' => InstanceSettings::get() ]); } + public function license() { if (!isCloud()) { @@ -36,6 +35,7 @@ public function license() 'settings' => InstanceSettings::get() ]); } + public function dashboard() { $projects = Project::ownedByCurrentTeam()->get(); @@ -55,6 +55,7 @@ public function dashboard() 's3s' => $s3s, ]); } + public function settings() { if (auth()->user()->isInstanceAdmin()) { @@ -66,6 +67,7 @@ public function settings() return redirect()->route('dashboard'); } } + public function emails() { if (auth()->user()->isInstanceAdmin()) { @@ -77,6 +79,7 @@ public function emails() return redirect()->route('dashboard'); } } + public function team() { $invitations = []; @@ -87,18 +90,23 @@ public function team() 'invitations' => $invitations, ]); } - public function storages() { + + public function storages() + { $s3 = S3Storage::ownedByCurrentTeam()->get(); return view('team.storages.all', [ 's3' => $s3, ]); } - public function storages_show() { + + public function storages_show() + { $storage = S3Storage::ownedByCurrentTeam()->whereUuid(request()->storage_uuid)->firstOrFail(); return view('team.storages.show', [ 'storage' => $storage, ]); } + public function members() { $invitations = []; @@ -109,6 +117,7 @@ public function members() 'invitations' => $invitations, ]); } + public function acceptInvitation() { try { @@ -135,6 +144,7 @@ public function acceptInvitation() throw $th; } } + public function revokeInvitation() { try { @@ -152,4 +162,4 @@ public function revokeInvitation() throw $th; } } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/DatabaseController.php b/app/Http/Controllers/DatabaseController.php index 6137c8a6b..33da43d83 100644 --- a/app/Http/Controllers/DatabaseController.php +++ b/app/Http/Controllers/DatabaseController.php @@ -2,15 +2,13 @@ namespace App\Http\Controllers; -use App\Models\ApplicationDeploymentQueue; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Validation\ValidatesRequests; -use Illuminate\Http\Request; -use Spatie\Activitylog\Models\Activity; class DatabaseController extends Controller { use AuthorizesRequests, ValidatesRequests; + public function configuration() { $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); diff --git a/app/Http/Controllers/MagicController.php b/app/Http/Controllers/MagicController.php index c4f77805a..e461cc70c 100644 --- a/app/Http/Controllers/MagicController.php +++ b/app/Http/Controllers/MagicController.php @@ -2,7 +2,6 @@ namespace App\Http\Controllers; -use App\Http\Livewire\Server\PrivateKey; use App\Models\Environment; use App\Models\Project; use App\Models\Server; @@ -16,24 +15,28 @@ public function servers() 'servers' => Server::isUsable()->get() ]); } + public function destinations() { return response()->json([ 'destinations' => Server::destinationsByServer(request()->query('server_id'))->sortBy('name') ]); } + public function projects() { return response()->json([ 'projects' => Project::ownedByCurrentTeam()->get() ]); } + public function environments() { return response()->json([ 'environments' => Project::ownedByCurrentTeam()->whereUuid(request()->query('project_uuid'))->first()->environments ]); } + public function newProject() { $project = Project::firstOrCreate( @@ -44,6 +47,7 @@ public function newProject() 'project_uuid' => $project->uuid ]); } + public function newEnvironment() { $environment = Environment::firstOrCreate( @@ -54,6 +58,7 @@ public function newEnvironment() 'environment_name' => $environment->name, ]); } + public function newTeam() { $team = Team::create( diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index e56edf17b..80cdc7b47 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -25,6 +25,7 @@ public function edit() } return view('project.edit', ['project' => $project]); } + public function show() { $projectUuid = request()->route('project_uuid'); @@ -55,6 +56,7 @@ public function new() 'type' => $type ]); } + public function resources() { $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); diff --git a/app/Http/Livewire/ActivityMonitor.php b/app/Http/Livewire/ActivityMonitor.php index 1ce763a0f..339ae4df4 100644 --- a/app/Http/Livewire/ActivityMonitor.php +++ b/app/Http/Livewire/ActivityMonitor.php @@ -15,12 +15,6 @@ class ActivityMonitor extends Component protected $activity; protected $listeners = ['newMonitorActivity']; - public function hydrateActivity() - { - $this->activity = Activity::query() - ->find($this->activityId); - } - public function newMonitorActivity($activityId) { $this->activityId = $activityId; @@ -30,6 +24,12 @@ public function newMonitorActivity($activityId) $this->isPollingActive = true; } + public function hydrateActivity() + { + $this->activity = Activity::query() + ->find($this->activityId); + } + public function polling() { $this->hydrateActivity(); @@ -45,6 +45,7 @@ public function polling() $this->emit('activityFinished'); } } + protected function setStatus($status) { $this->activity->properties = $this->activity->properties->merge([ @@ -52,4 +53,4 @@ protected function setStatus($status) ]); $this->activity->save(); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/CheckLicense.php b/app/Http/Livewire/CheckLicense.php index 7e6f07e26..3afefed34 100644 --- a/app/Http/Livewire/CheckLicense.php +++ b/app/Http/Livewire/CheckLicense.php @@ -19,11 +19,13 @@ class CheckLicense extends Component 'instance_id' => 'Instance Id (Do not change this)', 'settings.is_resale_license_active' => 'Is License Active', ]; + public function mount() { $this->instance_id = config('app.id'); $this->settings = InstanceSettings::get(); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Destination/Form.php b/app/Http/Livewire/Destination/Form.php index 4f400a670..56c7ba5ed 100644 --- a/app/Http/Livewire/Destination/Form.php +++ b/app/Http/Livewire/Destination/Form.php @@ -18,11 +18,13 @@ class Form extends Component 'destination.network' => 'network', 'destination.server.ip' => 'IP Address', ]; + public function submit() { $this->validate(); $this->destination->save(); } + public function delete() { try { diff --git a/app/Http/Livewire/Destination/New/StandaloneDocker.php b/app/Http/Livewire/Destination/New/StandaloneDocker.php index e43b1df6e..da4c453b7 100644 --- a/app/Http/Livewire/Destination/New/StandaloneDocker.php +++ b/app/Http/Livewire/Destination/New/StandaloneDocker.php @@ -5,9 +5,9 @@ use App\Models\Server; use App\Models\StandaloneDocker as ModelsStandaloneDocker; use Illuminate\Database\Eloquent\Collection; +use Illuminate\Support\Str; use Livewire\Component; use Visus\Cuid2\Cuid2; -use Illuminate\Support\Str; class StandaloneDocker extends Component { @@ -28,6 +28,7 @@ class StandaloneDocker extends Component 'network' => 'network', 'server_id' => 'server' ]; + public function mount() { if (request()->query('server_id')) { @@ -44,15 +45,13 @@ public function mount() } $this->name = Str::kebab("{$this->servers->first()->name}-{$this->network}"); } - public function generate_name() { + + public function generate_name() + { $this->server = Server::find($this->server_id); $this->name = Str::kebab("{$this->server->name}-{$this->network}"); } - private function createNetworkAndAttachToProxy() - { - instant_remote_process(['docker network create --attachable ' . $this->network], $this->server, throwError: false); - instant_remote_process(["docker network connect $this->network coolify-proxy"], $this->server, throwError: false); - } + public function submit() { $this->validate(); @@ -77,4 +76,10 @@ public function submit() return general_error_handler(err: $e); } } -} \ No newline at end of file + + private function createNetworkAndAttachToProxy() + { + instant_remote_process(['docker network create --attachable ' . $this->network], $this->server, throwError: false); + instant_remote_process(["docker network connect $this->network coolify-proxy"], $this->server, throwError: false); + } +} diff --git a/app/Http/Livewire/Destination/Show.php b/app/Http/Livewire/Destination/Show.php index df27e31df..d68537ac4 100644 --- a/app/Http/Livewire/Destination/Show.php +++ b/app/Http/Livewire/Destination/Show.php @@ -10,6 +10,7 @@ class Show extends Component { public Server $server; public Collection|array $networks = []; + public function scan() { $alreadyAddedNetworks = $this->server->standaloneDockers; diff --git a/app/Http/Livewire/Dev/S3Test.php b/app/Http/Livewire/Dev/S3Test.php index 7aaf732bc..0d67717fa 100644 --- a/app/Http/Livewire/Dev/S3Test.php +++ b/app/Http/Livewire/Dev/S3Test.php @@ -4,33 +4,39 @@ use App\Models\S3Storage; use Illuminate\Support\Facades\Storage; -use Livewire\WithFileUploads; use Livewire\Component; +use Livewire\WithFileUploads; class S3Test extends Component { use WithFileUploads; + public $s3; public $file; - public function mount() { + + public function mount() + { $this->s3 = S3Storage::first(); } - public function save() { + + public function save() + { try { $this->validate([ 'file' => 'required|max:150', // 1MB Max ]); set_s3_target($this->s3); - $this->file->storeAs('files', $this->file->getClientOriginalName(),'custom-s3'); + $this->file->storeAs('files', $this->file->getClientOriginalName(), 'custom-s3'); $this->emit('success', 'File uploaded successfully.'); } catch (\Throwable $th) { return general_error_handler($th, $this, false); } } + public function get_files() { set_s3_target($this->s3); dd(Storage::disk('custom-s3')->files('files')); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Notifications/DiscordSettings.php b/app/Http/Livewire/Notifications/DiscordSettings.php index e7dab8036..ac64c9184 100644 --- a/app/Http/Livewire/Notifications/DiscordSettings.php +++ b/app/Http/Livewire/Notifications/DiscordSettings.php @@ -19,6 +19,7 @@ class DiscordSettings extends Component protected $validationAttributes = [ 'model.discord_webhook_url' => 'Discord Webhook', ]; + public function instantSave() { try { @@ -29,6 +30,14 @@ public function instantSave() $this->validate(); } } + + public function submit() + { + $this->resetErrorBag(); + $this->validate(); + $this->saveModel(); + } + public function saveModel() { ray($this->model); @@ -38,15 +47,10 @@ public function saveModel() } $this->emit('success', 'Settings saved.'); } - public function submit() - { - $this->resetErrorBag(); - $this->validate(); - $this->saveModel(); - } + public function sendTestNotification() { $this->model->notify(new Test); $this->emit('success', 'Test notification sent.'); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Notifications/EmailSettings.php b/app/Http/Livewire/Notifications/EmailSettings.php index 243f147dc..8c7389afd 100644 --- a/app/Http/Livewire/Notifications/EmailSettings.php +++ b/app/Http/Livewire/Notifications/EmailSettings.php @@ -37,6 +37,13 @@ class EmailSettings extends Component 'model.smtp_username' => 'Username', 'model.smtp_password' => 'Password', ]; + + public function mount() + { + $this->decrypt(); + $this->emails = auth()->user()->email; + } + private function decrypt() { if (data_get($this->model, 'smtp_password')) { @@ -46,11 +53,7 @@ private function decrypt() } } } - public function mount() - { - $this->decrypt(); - $this->emails = auth()->user()->email; - } + public function copyFromInstanceSettings() { $settings = InstanceSettings::get(); @@ -78,6 +81,23 @@ public function copyFromInstanceSettings() $this->emit('error', 'Instance SMTP settings are not enabled.'); } } + + public function sendTestNotification() + { + $this->model->notify(new Test($this->emails)); + $this->emit('success', 'Test Email sent successfully.'); + } + + public function instantSave() + { + try { + $this->submit(); + } catch (\Exception $e) { + $this->model->smtp_enabled = false; + $this->validate(); + } + } + public function submit() { $this->resetErrorBag(); @@ -92,6 +112,7 @@ public function submit() $this->model->smtp_recipients = str_replace(' ', '', $this->model->smtp_recipients); $this->saveModel(); } + public function saveModel() { $this->model->save(); @@ -101,18 +122,4 @@ public function saveModel() } $this->emit('success', 'Settings saved.'); } - public function sendTestNotification() - { - $this->model->notify(new Test($this->emails)); - $this->emit('success', 'Test Email sent successfully.'); - } - public function instantSave() - { - try { - $this->submit(); - } catch (\Exception $e) { - $this->model->smtp_enabled = false; - $this->validate(); - } - } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/PrivateKey/Change.php b/app/Http/Livewire/PrivateKey/Change.php index 4f3ad4488..1274910b2 100644 --- a/app/Http/Livewire/PrivateKey/Change.php +++ b/app/Http/Livewire/PrivateKey/Change.php @@ -20,6 +20,7 @@ class Change extends Component 'private_key.description' => 'description', 'private_key.private_key' => 'private key' ]; + public function delete() { try { @@ -33,6 +34,7 @@ public function delete() return general_error_handler(err: $e, that: $this); } } + public function changePrivateKey() { try { diff --git a/app/Http/Livewire/PrivateKey/Create.php b/app/Http/Livewire/PrivateKey/Create.php index bfbf72e18..24e99cf85 100644 --- a/app/Http/Livewire/PrivateKey/Create.php +++ b/app/Http/Livewire/PrivateKey/Create.php @@ -19,6 +19,7 @@ class Create extends Component 'name' => 'name', 'value' => 'private Key', ]; + public function createPrivateKey() { $this->validate(); diff --git a/app/Http/Livewire/Profile/Form.php b/app/Http/Livewire/Profile/Form.php index 9075c4da2..926d638f1 100644 --- a/app/Http/Livewire/Profile/Form.php +++ b/app/Http/Livewire/Profile/Form.php @@ -17,12 +17,14 @@ class Form extends Component protected $validationAttributes = [ 'name' => 'name', ]; + public function mount() { $this->userId = auth()->user()->id; $this->name = auth()->user()->name; $this->email = auth()->user()->email; } + public function submit() { diff --git a/app/Http/Livewire/Project/AddEmpty.php b/app/Http/Livewire/Project/AddEmpty.php index 98136fb86..1024bc66f 100644 --- a/app/Http/Livewire/Project/AddEmpty.php +++ b/app/Http/Livewire/Project/AddEmpty.php @@ -17,6 +17,7 @@ class AddEmpty extends Component 'name' => 'Project Name', 'description' => 'Project Description', ]; + public function submit() { try { diff --git a/app/Http/Livewire/Project/AddEnvironment.php b/app/Http/Livewire/Project/AddEnvironment.php index 3ca6d8de3..ea38df073 100644 --- a/app/Http/Livewire/Project/AddEnvironment.php +++ b/app/Http/Livewire/Project/AddEnvironment.php @@ -17,6 +17,7 @@ class AddEnvironment extends Component protected $validationAttributes = [ 'name' => 'Environment Name', ]; + public function submit() { try { diff --git a/app/Http/Livewire/Project/Application/DeploymentLogs.php b/app/Http/Livewire/Project/Application/DeploymentLogs.php index b39cc47f7..ac3c4a6cf 100644 --- a/app/Http/Livewire/Project/Application/DeploymentLogs.php +++ b/app/Http/Livewire/Project/Application/DeploymentLogs.php @@ -10,10 +10,12 @@ class DeploymentLogs extends Component public ApplicationDeploymentQueue $application_deployment_queue; public $isKeepAliveOn = true; protected $listeners = ['refreshQueue']; + public function refreshQueue() { $this->application_deployment_queue->refresh(); } + public function polling() { $this->emit('deploymentFinished'); diff --git a/app/Http/Livewire/Project/Application/DeploymentNavbar.php b/app/Http/Livewire/Project/Application/DeploymentNavbar.php index 412f15956..1646d46e0 100644 --- a/app/Http/Livewire/Project/Application/DeploymentNavbar.php +++ b/app/Http/Livewire/Project/Application/DeploymentNavbar.php @@ -8,17 +8,16 @@ use App\Models\Server; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Process; -use Livewire\Component; use Illuminate\Support\Str; +use Livewire\Component; class DeploymentNavbar extends Component { - protected $listeners = ['deploymentFinished']; - public ApplicationDeploymentQueue $application_deployment_queue; public Application $application; public Server $server; public bool $is_debug_enabled = false; + protected $listeners = ['deploymentFinished']; public function mount() { @@ -26,10 +25,12 @@ public function mount() $this->server = $this->application->destination->server; $this->is_debug_enabled = $this->application->settings->is_debug_enabled; } + public function deploymentFinished() { $this->application_deployment_queue->refresh(); } + public function show_debug() { $this->application->settings->is_debug_enabled = !$this->application->settings->is_debug_enabled; @@ -37,6 +38,7 @@ public function show_debug() $this->is_debug_enabled = $this->application->settings->is_debug_enabled; $this->emit('refreshQueue'); } + public function cancel() { try { @@ -66,4 +68,4 @@ public function cancel() return general_error_handler(err: $e, that: $this); } } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Project/Application/Deployments.php b/app/Http/Livewire/Project/Application/Deployments.php index 16b40895b..1dd80d710 100644 --- a/app/Http/Livewire/Project/Application/Deployments.php +++ b/app/Http/Livewire/Project/Application/Deployments.php @@ -20,6 +20,7 @@ public function mount() $this->current_url = url()->current(); $this->show_more(); } + private function show_more() { if (count($this->deployments) !== 0) { @@ -30,10 +31,12 @@ private function show_more() return; } } + public function reload_deployments() { $this->load_deployments(); } + public function load_deployments(int|null $take = null) { if ($take) { diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index 2d15489fb..53416ae00 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -4,8 +4,8 @@ use App\Models\Application; use App\Models\InstanceSettings; -use Livewire\Component; use Illuminate\Support\Str; +use Livewire\Component; use Spatie\Url\Url; class General extends Component @@ -65,6 +65,7 @@ class General extends Component 'application.ports_exposes' => 'Ports exposes', 'application.ports_mappings' => 'Ports mappings', ]; + public function instantSave() { // @TODO: find another way - if possible @@ -86,6 +87,7 @@ public function instantSave() $this->emit('success', 'Application settings updated!'); $this->checkWildCardDomain(); } + protected function checkWildCardDomain() { $coolify_instance_settings = InstanceSettings::get(); @@ -93,6 +95,7 @@ protected function checkWildCardDomain() $this->global_wildcard_domain = data_get($coolify_instance_settings, 'wildcard_domain'); $this->wildcard_domain = $this->server_wildcard_domain ?? $this->global_wildcard_domain ?? null; } + public function mount() { $this->is_static = $this->application->settings->is_static; @@ -104,6 +107,7 @@ public function mount() $this->is_force_https_enabled = $this->application->settings->is_force_https_enabled; $this->checkWildCardDomain(); } + public function generateGlobalRandomDomain() { // Set wildcard domain based on Global wildcard domain @@ -115,6 +119,7 @@ public function generateGlobalRandomDomain() $this->application->save(); $this->emit('success', 'Application settings updated!'); } + public function generateServerRandomDomain() { // Set wildcard domain based on Server wildcard domain @@ -126,6 +131,7 @@ public function generateServerRandomDomain() $this->application->save(); $this->emit('success', 'Application settings updated!'); } + public function submit() { try { diff --git a/app/Http/Livewire/Project/Application/Heading.php b/app/Http/Livewire/Project/Application/Heading.php index b3c3cd876..41b84bb15 100644 --- a/app/Http/Livewire/Project/Application/Heading.php +++ b/app/Http/Livewire/Project/Application/Heading.php @@ -28,6 +28,12 @@ public function check_status() )); $this->application->refresh(); } + + public function force_deploy_without_cache() + { + $this->deploy(force_rebuild: true); + } + public function deploy(bool $force_rebuild = false) { $this->setDeploymentUuid(); @@ -43,10 +49,13 @@ public function deploy(bool $force_rebuild = false) 'environment_name' => $this->parameters['environment_name'], ]); } - public function force_deploy_without_cache() + + protected function setDeploymentUuid() { - $this->deploy(force_rebuild: true); + $this->deploymentUuid = new Cuid2(7); + $this->parameters['deployment_uuid'] = $this->deploymentUuid; } + public function stop() { remote_process( @@ -57,9 +66,4 @@ public function stop() $this->application->save(); $this->application->environment->project->team->notify(new StatusChanged($this->application)); } - protected function setDeploymentUuid() - { - $this->deploymentUuid = new Cuid2(7); - $this->parameters['deployment_uuid'] = $this->deploymentUuid; - } } diff --git a/app/Http/Livewire/Project/Application/Preview/Form.php b/app/Http/Livewire/Project/Application/Preview/Form.php index e17312005..f831b487d 100644 --- a/app/Http/Livewire/Project/Application/Preview/Form.php +++ b/app/Http/Livewire/Project/Application/Preview/Form.php @@ -17,6 +17,7 @@ class Form extends Component protected $validationAttributes = [ 'application.preview_url_template' => 'preview url template', ]; + public function resetToDefault() { $this->application->preview_url_template = '{{pr_id}}.{{domain}}'; @@ -24,6 +25,7 @@ public function resetToDefault() $this->application->save(); $this->generate_real_url(); } + public function generate_real_url() { if (data_get($this->application, 'fqdn')) { @@ -32,10 +34,12 @@ public function generate_real_url() $this->preview_url_template = Str::of($this->application->preview_url_template)->replace('{{domain}}', $host); } } + public function mount() { $this->generate_real_url(); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Project/Application/Previews.php b/app/Http/Livewire/Project/Application/Previews.php index a708a7098..f6f493827 100644 --- a/app/Http/Livewire/Project/Application/Previews.php +++ b/app/Http/Livewire/Project/Application/Previews.php @@ -22,6 +22,7 @@ public function mount() $this->pull_requests = collect(); $this->parameters = getRouteParameters(); } + public function loadStatus($pull_request_id) { dispatch(new ContainerStatusJob( @@ -30,11 +31,7 @@ public function loadStatus($pull_request_id) pull_request_id: $pull_request_id )); } - protected function setDeploymentUuid() - { - $this->deployment_uuid = new Cuid2(7); - $this->parameters['deployment_uuid'] = $this->deployment_uuid; - } + public function load_prs() { try { @@ -46,6 +43,7 @@ public function load_prs() return general_error_handler(err: $e, that: $this); } } + public function deploy(int $pull_request_id, string|null $pull_request_html_url = null) { try { @@ -74,6 +72,13 @@ public function deploy(int $pull_request_id, string|null $pull_request_html_url return general_error_handler(err: $e, that: $this); } } + + protected function setDeploymentUuid() + { + $this->deployment_uuid = new Cuid2(7); + $this->parameters['deployment_uuid'] = $this->deployment_uuid; + } + public function stop(int $pull_request_id) { try { @@ -87,6 +92,7 @@ public function stop(int $pull_request_id) return general_error_handler(err: $e, that: $this); } } + public function previewRefresh() { $this->application->previews->each(function ($preview) { diff --git a/app/Http/Livewire/Project/Application/Rollback.php b/app/Http/Livewire/Project/Application/Rollback.php index 2e708ec36..ee827b206 100644 --- a/app/Http/Livewire/Project/Application/Rollback.php +++ b/app/Http/Livewire/Project/Application/Rollback.php @@ -3,8 +3,8 @@ namespace App\Http\Livewire\Project\Application; use App\Models\Application; -use Livewire\Component; use Illuminate\Support\Str; +use Livewire\Component; use Visus\Cuid2\Cuid2; class Rollback extends Component @@ -18,6 +18,7 @@ public function mount() { $this->parameters = getRouteParameters(); } + public function rollbackImage($commit) { $deployment_uuid = new Cuid2(7); @@ -36,6 +37,7 @@ public function rollbackImage($commit) 'environment_name' => $this->parameters['environment_name'], ]); } + public function loadImages() { try { diff --git a/app/Http/Livewire/Project/Application/Source.php b/app/Http/Livewire/Project/Application/Source.php index 83b457ae5..1fec460d9 100644 --- a/app/Http/Livewire/Project/Application/Source.php +++ b/app/Http/Livewire/Project/Application/Source.php @@ -21,16 +21,19 @@ class Source extends Component 'application.git_branch' => 'branch', 'application.git_commit_sha' => 'commit sha', ]; + + public function mount() + { + $this->get_private_keys(); + } + private function get_private_keys() { $this->private_keys = PrivateKey::whereTeamId(session('currentTeam')->id)->get()->reject(function ($key) { return $key->id == $this->application->private_key_id; }); } - public function mount() - { - $this->get_private_keys(); - } + public function setPrivateKey(int $private_key_id) { $this->application->private_key_id = $private_key_id; @@ -38,6 +41,7 @@ public function setPrivateKey(int $private_key_id) $this->application->refresh(); $this->get_private_keys(); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Project/Database/Heading.php b/app/Http/Livewire/Project/Database/Heading.php index f6dd7a12d..300804bad 100644 --- a/app/Http/Livewire/Project/Database/Heading.php +++ b/app/Http/Livewire/Project/Database/Heading.php @@ -2,10 +2,10 @@ namespace App\Http\Livewire\Project\Database; -use Livewire\Component; use App\Actions\Database\StartPostgresql; use App\Jobs\ContainerStatusJob; use App\Notifications\Application\StatusChanged; +use Livewire\Component; class Heading extends Component { @@ -13,13 +13,16 @@ class Heading extends Component public array $parameters; protected $listeners = ['activityFinished']; - public function activityFinished() { + + public function activityFinished() + { $this->database->update([ 'started_at' => now(), ]); $this->emit('refresh'); $this->check_status(); } + public function check_status() { dispatch_sync(new ContainerStatusJob( @@ -28,11 +31,14 @@ public function check_status() )); $this->database->refresh(); } + public function mount() { $this->parameters = getRouteParameters(); } - public function stop() { + + public function stop() + { remote_process( ["docker rm -f {$this->database->uuid}"], $this->database->destination->server @@ -41,7 +47,9 @@ public function stop() { $this->database->save(); $this->database->environment->project->team->notify(new StatusChanged($this->database)); } - public function start() { + + public function start() + { if ($this->database->type() === 'standalone-postgresql') { $activity = resolve(StartPostgresql::class)($this->database->destination->server, $this->database); $this->emit('newMonitorActivity', $activity->id); diff --git a/app/Http/Livewire/Project/Database/Postgresql/General.php b/app/Http/Livewire/Project/Database/Postgresql/General.php index 8b1d6c40a..9a0e0d22f 100644 --- a/app/Http/Livewire/Project/Database/Postgresql/General.php +++ b/app/Http/Livewire/Project/Database/Postgresql/General.php @@ -31,10 +31,14 @@ class General extends Component 'database.init_scripts' => 'Init Scripts', 'database.image' => 'Image', ]; - public function refresh() { + + public function refresh(): void + { $this->database->refresh(); } - public function submit() { + + public function submit() + { try { $this->validate(); $this->database->save(); diff --git a/app/Http/Livewire/Project/DeleteEnvironment.php b/app/Http/Livewire/Project/DeleteEnvironment.php index 9e712d859..da08b5fc6 100644 --- a/app/Http/Livewire/Project/DeleteEnvironment.php +++ b/app/Http/Livewire/Project/DeleteEnvironment.php @@ -14,6 +14,7 @@ public function mount() { $this->parameters = getRouteParameters(); } + public function delete() { $this->validate([ diff --git a/app/Http/Livewire/Project/DeleteProject.php b/app/Http/Livewire/Project/DeleteProject.php index 1a22e6257..bfb1b683c 100644 --- a/app/Http/Livewire/Project/DeleteProject.php +++ b/app/Http/Livewire/Project/DeleteProject.php @@ -14,6 +14,7 @@ public function mount() { $this->parameters = getRouteParameters(); } + public function delete() { $this->validate([ diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepository.php b/app/Http/Livewire/Project/New/GithubPrivateRepository.php index 535227ac9..dcd4b8c81 100644 --- a/app/Http/Livewire/Project/New/GithubPrivateRepository.php +++ b/app/Http/Livewire/Project/New/GithubPrivateRepository.php @@ -5,12 +5,9 @@ use App\Models\Application; use App\Models\GithubApp; use App\Models\Project; -use App\Models\Server; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; -use Illuminate\Support\Collection; use Illuminate\Support\Facades\Http; -use Illuminate\Support\Facades\Log; use Livewire\Component; class GithubPrivateRepository extends Component @@ -30,18 +27,14 @@ class GithubPrivateRepository extends Component public string $selected_branch_name = 'main'; public string $token; - - protected int $page = 1; - public $repositories; public int $total_repositories_count = 0; - public $branches; public int $total_branches_count = 0; - public int $port = 3000; public bool $is_static = false; public string|null $publish_directory = null; + protected int $page = 1; public function mount() { @@ -50,32 +43,7 @@ public function mount() $this->repositories = $this->branches = collect(); $this->github_apps = GithubApp::private(); } - protected function loadRepositoryByPage() - { - $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/installation/repositories?per_page=100&page={$this->page}"); - $json = $response->json(); - if ($response->status() !== 200) { - return $this->emit('error', $json['message']); - } - if ($json['total_count'] === 0) { - return; - } - $this->total_repositories_count = $json['total_count']; - $this->repositories = $this->repositories->concat(collect($json['repositories'])); - } - protected function loadBranchByPage() - { - ray('Loading page ' . $this->page); - $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/repos/{$this->selected_repository_owner}/{$this->selected_repository_repo}/branches?per_page=100&page={$this->page}"); - $json = $response->json(); - if ($response->status() !== 200) { - return $this->emit('error', $json['message']); - } - - $this->total_branches_count = count($json); - $this->branches = $this->branches->concat(collect($json)); - } public function loadRepositories($github_app_id) { $this->repositories = collect(); @@ -93,6 +61,22 @@ public function loadRepositories($github_app_id) $this->selected_repository_id = $this->repositories[0]['id']; $this->current_step = 'repository'; } + + protected function loadRepositoryByPage() + { + $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/installation/repositories?per_page=100&page={$this->page}"); + $json = $response->json(); + if ($response->status() !== 200) { + return $this->emit('error', $json['message']); + } + + if ($json['total_count'] === 0) { + return; + } + $this->total_repositories_count = $json['total_count']; + $this->repositories = $this->repositories->concat(collect($json['repositories'])); + } + public function loadBranches() { $this->selected_repository_owner = $this->repositories->where('id', $this->selected_repository_id)->first()['owner']['login']; @@ -107,6 +91,20 @@ public function loadBranches() } } } + + protected function loadBranchByPage() + { + ray('Loading page ' . $this->page); + $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/repos/{$this->selected_repository_owner}/{$this->selected_repository_repo}/branches?per_page=100&page={$this->page}"); + $json = $response->json(); + if ($response->status() !== 200) { + return $this->emit('error', $json['message']); + } + + $this->total_branches_count = count($json); + $this->branches = $this->branches->concat(collect($json)); + } + public function submit() { try { @@ -136,7 +134,7 @@ public function submit() 'destination_id' => $destination->id, 'destination_type' => $destination_class, 'source_id' => $this->github_app->id, - 'source_type' => $this->github_app->getMorphClass() + 'source_type' => $this->github_app->getMorphClass() ]); $application->settings->is_static = $this->is_static; $application->settings->save(); @@ -150,6 +148,7 @@ public function submit() return general_error_handler(err: $e, that: $this); } } + public function instantSave() { if ($this->is_static) { diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php index cfb528f1e..afc0062a0 100644 --- a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php +++ b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php @@ -27,14 +27,7 @@ class GithubPrivateRepositoryDeployKey extends Component public null|string $publish_directory = null; public string $repository_url; - private object $repository_url_parsed; public string $branch; - - private GithubApp|GitlabApp $git_source; - private string $git_host; - private string $git_repository; - private string $git_branch; - protected $rules = [ 'repository_url' => 'required|url', 'branch' => 'required|string', @@ -49,6 +42,12 @@ class GithubPrivateRepositoryDeployKey extends Component 'is_static' => 'Is static', 'publish_directory' => 'Publish directory', ]; + private object $repository_url_parsed; + private GithubApp|GitlabApp $git_source; + private string $git_host; + private string $git_repository; + private string $git_branch; + public function mount() { if (isDev()) { @@ -58,6 +57,7 @@ public function mount() $this->query = request()->query(); $this->private_keys = PrivateKey::where('team_id', session('currentTeam')->id)->where('id', '!=', 0)->get(); } + public function instantSave() { if ($this->is_static) { @@ -68,30 +68,13 @@ public function instantSave() $this->publish_directory = null; } } + public function setPrivateKey($private_key_id) { $this->private_key_id = $private_key_id; $this->current_step = 'repository'; } - private function get_git_source() - { - $this->repository_url_parsed = Url::fromString($this->repository_url); - $this->git_host = $this->repository_url_parsed->getHost(); - $this->git_repository = $this->repository_url_parsed->getSegment(1) . '/' . $this->repository_url_parsed->getSegment(2); - if ($this->branch) { - $this->git_branch = $this->branch; - } else { - $this->git_branch = $this->repository_url_parsed->getSegment(4) ?? 'main'; - } - if ($this->git_host == 'github.com') { - $this->git_source = GithubApp::where('name', 'Public GitHub')->first(); - } elseif ($this->git_host == 'gitlab.com') { - $this->git_source = GitlabApp::where('name', 'Public GitLab')->first(); - } elseif ($this->git_host == 'bitbucket.org') { - // Not supported yet - } - } public function submit() { $this->validate(); @@ -123,7 +106,7 @@ public function submit() 'destination_type' => $destination_class, 'private_key_id' => $this->private_key_id, 'source_id' => $this->git_source->id, - 'source_type' => $this->git_source->getMorphClass() + 'source_type' => $this->git_source->getMorphClass() ]; $application = Application::create($application_init); $application->settings->is_static = $this->is_static; @@ -138,4 +121,24 @@ public function submit() return general_error_handler(err: $e, that: $this); } } + + private function get_git_source() + { + $this->repository_url_parsed = Url::fromString($this->repository_url); + $this->git_host = $this->repository_url_parsed->getHost(); + $this->git_repository = $this->repository_url_parsed->getSegment(1) . '/' . $this->repository_url_parsed->getSegment(2); + if ($this->branch) { + $this->git_branch = $this->branch; + } else { + $this->git_branch = $this->repository_url_parsed->getSegment(4) ?? 'main'; + } + + if ($this->git_host == 'github.com') { + $this->git_source = GithubApp::where('name', 'Public GitHub')->first(); + } elseif ($this->git_host == 'gitlab.com') { + $this->git_source = GitlabApp::where('name', 'Public GitLab')->first(); + } elseif ($this->git_host == 'bitbucket.org') { + // Not supported yet + } + } } diff --git a/app/Http/Livewire/Project/New/PublicGitRepository.php b/app/Http/Livewire/Project/New/PublicGitRepository.php index 181a308bd..a610bf47b 100644 --- a/app/Http/Livewire/Project/New/PublicGitRepository.php +++ b/app/Http/Livewire/Project/New/PublicGitRepository.php @@ -15,13 +15,10 @@ class PublicGitRepository extends Component { public string $repository_url; - private object $repository_url_parsed; - public int $port = 3000; public string $type; public $parameters; public $query; - public bool $branch_found = false; public string $selected_branch = 'main'; public bool $is_static = false; @@ -29,11 +26,6 @@ class PublicGitRepository extends Component public string $git_branch = 'main'; public int $rate_limit_remaining = 0; public $rate_limit_reset = 0; - - private GithubApp|GitlabApp $git_source; - private string $git_host; - private string $git_repository; - protected $rules = [ 'repository_url' => 'required|url', 'port' => 'required|numeric', @@ -46,6 +38,11 @@ class PublicGitRepository extends Component 'is_static' => 'static', 'publish_directory' => 'publish directory', ]; + private object $repository_url_parsed; + private GithubApp|GitlabApp $git_source; + private string $git_host; + private string $git_repository; + public function mount() { if (isDev()) { @@ -67,12 +64,7 @@ public function instantSave() } $this->emit('success', 'Application settings updated!'); } - private function get_branch() - { - ['rate_limit_remaining' => $this->rate_limit_remaining, 'rate_limit_reset' => $this->rate_limit_reset] = git_api(source: $this->git_source, endpoint: "/repos/{$this->git_repository}/branches/{$this->git_branch}"); - $this->rate_limit_reset = Carbon::parse((int)$this->rate_limit_reset)->format('Y-M-d H:i:s'); - $this->branch_found = true; - } + public function load_branch() { $this->branch_found = false; @@ -96,6 +88,7 @@ public function load_branch() } } } + private function get_git_source() { $this->repository_url_parsed = Url::fromString($this->repository_url); @@ -111,6 +104,14 @@ private function get_git_source() // Not supported yet } } + + private function get_branch() + { + ['rate_limit_remaining' => $this->rate_limit_remaining, 'rate_limit_reset' => $this->rate_limit_reset] = git_api(source: $this->git_source, endpoint: "/repos/{$this->git_repository}/branches/{$this->git_branch}"); + $this->rate_limit_reset = Carbon::parse((int)$this->rate_limit_reset)->format('Y-M-d H:i:s'); + $this->branch_found = true; + } + public function submit() { try { diff --git a/app/Http/Livewire/Project/New/Select.php b/app/Http/Livewire/Project/New/Select.php index 3e6137891..e09862649 100644 --- a/app/Http/Livewire/Project/New/Select.php +++ b/app/Http/Livewire/Project/New/Select.php @@ -19,17 +19,20 @@ public function mount() { $this->parameters = getRouteParameters(); } + public function set_type(string $type) { $this->type = $type; $this->current_step = 'servers'; } + public function set_server(Server $server) { $this->server_id = $server->id; $this->destinations = $server->destinations(); $this->current_step = 'destinations'; } + public function set_destination(string $destination_uuid) { $this->destination_uuid = $destination_uuid; @@ -40,6 +43,7 @@ public function set_destination(string $destination_uuid) 'destination' => $this->destination_uuid, ]); } + public function load_servers() { $this->servers = Server::ownedByCurrentTeam()->get(); diff --git a/app/Http/Livewire/Project/Shared/Danger.php b/app/Http/Livewire/Project/Shared/Danger.php index 0bb5f8ef6..3b5283ef2 100644 --- a/app/Http/Livewire/Project/Shared/Danger.php +++ b/app/Http/Livewire/Project/Shared/Danger.php @@ -16,6 +16,7 @@ public function mount() $this->modalId = new Cuid2(7); $this->parameters = getRouteParameters(); } + public function delete() { $destination = $this->resource->destination->getMorphClass()::where('id', $this->resource->destination->id)->first(); diff --git a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Add.php b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Add.php index 1512277e9..783c52183 100644 --- a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Add.php +++ b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Add.php @@ -23,10 +23,12 @@ class Add extends Component 'value' => 'value', 'is_build_time' => 'build', ]; + public function mount() { $this->parameters = getRouteParameters(); } + public function submit() { ray('submitting'); @@ -39,6 +41,7 @@ public function submit() ]); $this->clear(); } + public function clear() { $this->key = ''; diff --git a/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php b/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php index ffbaaa59b..70bfd42a1 100644 --- a/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php +++ b/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php @@ -11,14 +11,17 @@ class All extends Component public $resource; public string|null $modalId = null; protected $listeners = ['refreshEnvs', 'submit']; + public function mount() { $this->modalId = new Cuid2(7); } + public function refreshEnvs() { $this->resource->refresh(); } + public function submit($data) { try { @@ -27,16 +30,16 @@ public function submit($data) $this->emit('error', 'Environment variable already exists.'); return; } - $environment = new EnvironmentVariable(); + $environment = new EnvironmentVariable(); $environment->key = $data['key']; $environment->value = $data['value']; $environment->is_build_time = $data['is_build_time']; $environment->is_preview = $data['is_preview']; - if($this->resource->type() === 'application') { + if ($this->resource->type() === 'application') { $environment->application_id = $this->resource->id; } - if($this->resource->type() === 'standalone-postgresql') { + if ($this->resource->type() === 'standalone-postgresql') { $environment->standalone_postgresql_id = $this->resource->id; } $environment->save(); diff --git a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php index 1439e983d..f17ac8893 100644 --- a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php +++ b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php @@ -21,17 +21,20 @@ class Show extends Component 'value' => 'value', 'is_build_time' => 'build', ]; + public function mount() { $this->modalId = new Cuid2(7); $this->parameters = getRouteParameters(); } + public function submit() { $this->validate(); $this->env->save(); $this->emit('success', 'Environment variable updated successfully.'); } + public function delete() { $this->env->delete(); diff --git a/app/Http/Livewire/Project/Shared/ResourceLimits.php b/app/Http/Livewire/Project/Shared/ResourceLimits.php index 7ad60aa3b..6b4ae7e3a 100644 --- a/app/Http/Livewire/Project/Shared/ResourceLimits.php +++ b/app/Http/Livewire/Project/Shared/ResourceLimits.php @@ -25,6 +25,7 @@ class ResourceLimits extends Component 'resource.limits_cpuset' => 'cpuset', 'resource.limits_cpu_shares' => 'cpu shares', ]; + public function submit() { try { diff --git a/app/Http/Livewire/Project/Shared/Storages/Add.php b/app/Http/Livewire/Project/Shared/Storages/Add.php index 59a8213e1..afd7b408b 100644 --- a/app/Http/Livewire/Project/Shared/Storages/Add.php +++ b/app/Http/Livewire/Project/Shared/Storages/Add.php @@ -22,10 +22,12 @@ class Add extends Component 'mount_path' => 'mount', 'host_path' => 'host', ]; + public function mount() { $this->parameters = getRouteParameters(); } + public function submit() { $this->validate(); @@ -35,6 +37,7 @@ public function submit() 'host_path' => $this->host_path, ]); } + public function clear() { $this->name = ''; diff --git a/app/Http/Livewire/Project/Shared/Storages/All.php b/app/Http/Livewire/Project/Shared/Storages/All.php index f03cd4d04..ee016143b 100644 --- a/app/Http/Livewire/Project/Shared/Storages/All.php +++ b/app/Http/Livewire/Project/Shared/Storages/All.php @@ -9,10 +9,12 @@ class All extends Component { public $resource; protected $listeners = ['refreshStorages', 'submit']; + public function refreshStorages() { $this->resource->refresh(); } + public function submit($data) { try { diff --git a/app/Http/Livewire/Project/Shared/Storages/Show.php b/app/Http/Livewire/Project/Shared/Storages/Show.php index 6244537f7..7cbf322f7 100644 --- a/app/Http/Livewire/Project/Shared/Storages/Show.php +++ b/app/Http/Livewire/Project/Shared/Storages/Show.php @@ -19,16 +19,19 @@ class Show extends Component 'mount_path' => 'mount', 'host_path' => 'host', ]; + public function mount() { $this->modalId = new Cuid2(7); } + public function submit() { $this->validate(); $this->storage->save(); $this->emit('success', 'Storage updated successfully'); } + public function delete() { $this->storage->delete(); diff --git a/app/Http/Livewire/RunCommand.php b/app/Http/Livewire/RunCommand.php index 50462c52c..747ce9568 100755 --- a/app/Http/Livewire/RunCommand.php +++ b/app/Http/Livewire/RunCommand.php @@ -2,7 +2,6 @@ namespace App\Http\Livewire; -use App\Enums\ActivityTypes; use App\Models\Server; use Livewire\Component; @@ -20,6 +19,7 @@ class RunCommand extends Component 'server' => 'server', 'command' => 'command', ]; + public function mount($servers) { $this->servers = $servers; diff --git a/app/Http/Livewire/Server/Form.php b/app/Http/Livewire/Server/Form.php index ae7717967..d901dd2e6 100644 --- a/app/Http/Livewire/Server/Form.php +++ b/app/Http/Livewire/Server/Form.php @@ -5,7 +5,6 @@ use App\Actions\Server\InstallDocker; use App\Models\Server; use Livewire\Component; -use Visus\Cuid2\Cuid2; class Form extends Component { @@ -34,16 +33,19 @@ class Form extends Component 'server.settings.is_reachable' => 'is reachable', 'server.settings.is_part_of_swarm' => 'is part of swarm' ]; + public function mount() { $this->wildcard_domain = $this->server->settings->wildcard_domain; $this->cleanup_after_percentage = $this->server->settings->cleanup_after_percentage; } + public function installDocker() { $activity = resolve(InstallDocker::class)($this->server, session('currentTeam')); $this->emit('newMonitorActivity', $activity->id); } + public function validateServer() { try { @@ -59,6 +61,7 @@ public function validateServer() return general_error_handler(customErrorMessage: "Server is not reachable. Reason: {$e->getMessage()}", that: $this); } } + public function delete() { if (!$this->server->isEmpty()) { @@ -68,6 +71,7 @@ public function delete() $this->server->delete(); redirect()->route('server.all'); } + public function submit() { $this->validate(); @@ -88,4 +92,4 @@ public function submit() $this->server->save(); $this->emit('success', 'Server updated successfully.'); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Server/New/ByIp.php b/app/Http/Livewire/Server/New/ByIp.php index 424f31e1b..923bae039 100644 --- a/app/Http/Livewire/Server/New/ByIp.php +++ b/app/Http/Livewire/Server/New/ByIp.php @@ -2,7 +2,6 @@ namespace App\Http\Livewire\Server\New; -use App\Models\PrivateKey; use App\Models\Server; use Livewire\Component; @@ -35,19 +34,23 @@ class ByIp extends Component 'user' => 'user', 'port' => 'port', ]; + public function mount() { $this->name = generate_random_name(); $this->private_key_id = $this->private_keys->first()->id; } + public function setPrivateKey(string $private_key_id) { $this->private_key_id = $private_key_id; } + public function instantSave() { $this->emit('success', 'Application settings updated!'); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Server/PrivateKey.php b/app/Http/Livewire/Server/PrivateKey.php index 54035efba..4f9a1e022 100644 --- a/app/Http/Livewire/Server/PrivateKey.php +++ b/app/Http/Livewire/Server/PrivateKey.php @@ -3,7 +3,6 @@ namespace App\Http\Livewire\Server; use App\Models\Server; -use Illuminate\Support\Facades\Storage; use Livewire\Component; use Masmerise\Toaster\Toaster; @@ -13,6 +12,16 @@ class PrivateKey extends Component public $privateKeys; public $parameters; + public function setPrivateKey($private_key_id) + { + $this->server->update([ + 'private_key_id' => $private_key_id + ]); + refreshPrivateKey($this->server->privateKey); + $this->server->refresh(); + $this->checkConnection(); + } + public function checkConnection() { try { @@ -27,15 +36,7 @@ public function checkConnection() return general_error_handler(customErrorMessage: "Server is not reachable. Reason: {$e->getMessage()}", that: $this); } } - public function setPrivateKey($private_key_id) - { - $this->server->update([ - 'private_key_id' => $private_key_id - ]); - refreshPrivateKey($this->server->privateKey); - $this->server->refresh(); - $this->checkConnection(); - } + public function mount() { $this->parameters = getRouteParameters(); diff --git a/app/Http/Livewire/Server/Proxy.php b/app/Http/Livewire/Server/Proxy.php index 4e8680419..1f51d1b1c 100644 --- a/app/Http/Livewire/Server/Proxy.php +++ b/app/Http/Livewire/Server/Proxy.php @@ -5,7 +5,6 @@ use App\Actions\Proxy\CheckConfigurationSync; use App\Actions\Proxy\SaveConfigurationSync; use App\Enums\ProxyTypes; -use Illuminate\Support\Str; use App\Models\Server; use Livewire\Component; @@ -17,21 +16,25 @@ class Proxy extends Component public $proxy_settings = null; public string|null $redirect_url = null; - protected $listeners = ['proxyStatusUpdated', 'saveConfiguration'=>'submit']; + protected $listeners = ['proxyStatusUpdated', 'saveConfiguration' => 'submit']; + public function mount() { $this->redirect_url = $this->server->proxy->redirect_url; } + public function proxyStatusUpdated() { $this->server->refresh(); } + public function change_proxy() { $this->server->proxy = null; $this->server->save(); $this->emit('proxyStatusUpdated'); } + public function select_proxy(string $proxy_type) { $this->server->proxy->type = $proxy_type; @@ -39,6 +42,7 @@ public function select_proxy(string $proxy_type) $this->server->save(); $this->emit('proxyStatusUpdated'); } + public function submit() { try { @@ -53,6 +57,7 @@ public function submit() return general_error_handler(err: $e); } } + public function reset_proxy_configuration() { try { @@ -61,6 +66,7 @@ public function reset_proxy_configuration() return general_error_handler(err: $e); } } + public function load_proxy_configuration() { try { @@ -69,4 +75,4 @@ public function load_proxy_configuration() return general_error_handler(err: $e); } } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Server/Proxy/Deploy.php b/app/Http/Livewire/Server/Proxy/Deploy.php index 6ca4bca4b..9ec3898f1 100644 --- a/app/Http/Livewire/Server/Proxy/Deploy.php +++ b/app/Http/Livewire/Server/Proxy/Deploy.php @@ -5,12 +5,12 @@ use App\Actions\Proxy\StartProxy; use App\Models\Server; use Livewire\Component; -use Str; class Deploy extends Component { public Server $server; public $proxy_settings = null; + public function start_proxy() { if ( @@ -22,6 +22,7 @@ public function start_proxy() $activity = resolve(StartProxy::class)($this->server); $this->emit('newMonitorActivity', $activity->id); } + public function stop() { instant_remote_process([ @@ -31,4 +32,4 @@ public function stop() $this->server->save(); $this->emit('proxyStatusUpdated'); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Server/Proxy/Status.php b/app/Http/Livewire/Server/Proxy/Status.php index 8791e9cc4..a4a29b7c2 100644 --- a/app/Http/Livewire/Server/Proxy/Status.php +++ b/app/Http/Livewire/Server/Proxy/Status.php @@ -9,6 +9,7 @@ class Status extends Component { public Server $server; + public function get_status() { dispatch_sync(new ProxyContainerStatusJob( @@ -17,4 +18,4 @@ public function get_status() $this->server->refresh(); $this->emit('proxyStatusUpdated'); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Settings/Configuration.php b/app/Http/Livewire/Settings/Configuration.php index 98371d136..e4b7eb3f6 100644 --- a/app/Http/Livewire/Settings/Configuration.php +++ b/app/Http/Livewire/Settings/Configuration.php @@ -31,6 +31,7 @@ class Configuration extends Component 'settings.public_port_min' => 'Public port min', 'settings.public_port_max' => 'Public port max', ]; + public function mount() { $this->do_not_track = $this->settings->do_not_track; @@ -38,6 +39,7 @@ public function mount() $this->is_registration_enabled = $this->settings->is_registration_enabled; $this->next_channel = $this->settings->next_channel; } + public function instantSave() { $this->settings->do_not_track = $this->do_not_track; @@ -47,6 +49,21 @@ public function instantSave() $this->settings->save(); $this->emit('success', 'Settings updated!'); } + + public function submit() + { + $this->resetErrorBag(); + if ($this->settings->public_port_min > $this->settings->public_port_max) { + $this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.'); + return; + } + $this->validate(); + $this->settings->save(); + $this->server = Server::findOrFail(0); + $this->setup_instance_fqdn(); + $this->emit('success', 'Instance settings updated successfully!'); + } + private function setup_instance_fqdn() { $file = "$this->dynamic_config_path/coolify.yaml"; @@ -60,35 +77,35 @@ private function setup_instance_fqdn() $schema = $url->getScheme(); $traefik_dynamic_conf = [ 'http' => - [ - 'routers' => [ - 'coolify-http' => - [ - 'entryPoints' => [ - 0 => 'http', - ], - 'service' => 'coolify', - 'rule' => "Host(`{$host}`)", - ], - ], - 'services' => - [ - 'coolify' => - [ - 'loadBalancer' => + 'routers' => [ - 'servers' => - [ - 0 => + 'coolify-http' => [ - 'url' => 'http://coolify:80', + 'entryPoints' => [ + 0 => 'http', + ], + 'service' => 'coolify', + 'rule' => "Host(`{$host}`)", + ], + ], + 'services' => + [ + 'coolify' => + [ + 'loadBalancer' => + [ + 'servers' => + [ + 0 => + [ + 'url' => 'http://coolify:80', + ], + ], + ], ], - ], ], - ], ], - ], ]; if ($schema === 'https') { @@ -110,6 +127,7 @@ private function setup_instance_fqdn() dispatch(new ProxyStartJob($this->server)); } } + private function save_configuration_to_disk(array $traefik_dynamic_conf, string $file) { $yaml = Yaml::dump($traefik_dynamic_conf, 12, 2); @@ -128,17 +146,4 @@ private function save_configuration_to_disk(array $traefik_dynamic_conf, string ray($yaml); } } - public function submit() - { - $this->resetErrorBag(); - if ($this->settings->public_port_min > $this->settings->public_port_max) { - $this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.'); - return; - } - $this->validate(); - $this->settings->save(); - $this->server = Server::findOrFail(0); - $this->setup_instance_fqdn(); - $this->emit('success', 'Instance settings updated successfully!'); - } } diff --git a/app/Http/Livewire/Settings/Email.php b/app/Http/Livewire/Settings/Email.php index cd096e194..a0ac3c904 100644 --- a/app/Http/Livewire/Settings/Email.php +++ b/app/Http/Livewire/Settings/Email.php @@ -4,7 +4,6 @@ use App\Models\InstanceSettings; use App\Notifications\TransactionalEmails\Test; -use Illuminate\Support\Facades\Notification; use Livewire\Component; class Email extends Component @@ -32,11 +31,23 @@ class Email extends Component 'settings.smtp_username' => 'Username', 'settings.smtp_password' => 'Password', ]; + public function mount() { $this->decrypt(); $this->emails = auth()->user()->email; } + + private function decrypt() + { + if (data_get($this->settings, 'smtp_password')) { + try { + $this->settings->smtp_password = decrypt($this->settings->smtp_password); + } catch (\Exception $e) { + } + } + } + public function instantSave() { try { @@ -47,20 +58,7 @@ public function instantSave() $this->validate(); } } - public function sendTestNotification() - { - $this->settings->notify(new Test($this->emails)); - $this->emit('success', 'Test email sent.'); - } - private function decrypt() - { - if (data_get($this->settings, 'smtp_password')) { - try { - $this->settings->smtp_password = decrypt($this->settings->smtp_password); - } catch (\Exception $e) { - } - } - } + public function submit() { $this->resetErrorBag(); @@ -75,4 +73,10 @@ public function submit() $this->emit('success', 'Transaction email settings updated successfully.'); $this->decrypt(); } -} \ No newline at end of file + + public function sendTestNotification() + { + $this->settings->notify(new Test($this->emails)); + $this->emit('success', 'Test email sent.'); + } +} diff --git a/app/Http/Livewire/Source/Github/Change.php b/app/Http/Livewire/Source/Github/Change.php index 7908b179c..b85575cd5 100644 --- a/app/Http/Livewire/Source/Github/Change.php +++ b/app/Http/Livewire/Source/Github/Change.php @@ -34,12 +34,14 @@ class Change extends Component 'github_app.webhook_secret' => 'nullable', 'github_app.is_system_wide' => 'required|bool', ]; + public function mount() { $this->webhook_endpoint = $this->ipv4; $this->parameters = getRouteParameters(); $this->is_system_wide = $this->github_app->is_system_wide; } + public function submit() { try { @@ -49,6 +51,7 @@ public function submit() return general_error_handler(err: $e, that: $this); } } + public function instantSave() { } diff --git a/app/Http/Livewire/Source/Github/Create.php b/app/Http/Livewire/Source/Github/Create.php index b95bde919..29ff37dfc 100644 --- a/app/Http/Livewire/Source/Github/Create.php +++ b/app/Http/Livewire/Source/Github/Create.php @@ -19,6 +19,7 @@ public function mount() { $this->name = generate_random_name(); } + public function createGitHubApp() { try { diff --git a/app/Http/Livewire/SwitchTeam.php b/app/Http/Livewire/SwitchTeam.php index 109167dfe..087a7ad84 100644 --- a/app/Http/Livewire/SwitchTeam.php +++ b/app/Http/Livewire/SwitchTeam.php @@ -8,10 +8,12 @@ class SwitchTeam extends Component { public string $selectedTeamId = 'default'; + public function updatedSelectedTeamId() { $this->switch_to($this->selectedTeamId); } + public function switch_to($team_id) { if (!auth()->user()->teams->contains($team_id)) { diff --git a/app/Http/Livewire/Team/Create.php b/app/Http/Livewire/Team/Create.php index 5aa07bc94..6c1c71580 100644 --- a/app/Http/Livewire/Team/Create.php +++ b/app/Http/Livewire/Team/Create.php @@ -18,6 +18,7 @@ class Create extends Component 'name' => 'name', 'description' => 'description', ]; + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Team/Form.php b/app/Http/Livewire/Team/Form.php index f60f72523..56bd21db6 100644 --- a/app/Http/Livewire/Team/Form.php +++ b/app/Http/Livewire/Team/Form.php @@ -4,7 +4,6 @@ use App\Models\Team; use Livewire\Component; -use Masmerise\Toaster\Toaster; class Form extends Component { @@ -17,10 +16,12 @@ class Form extends Component 'team.name' => 'name', 'team.description' => 'description', ]; + public function mount() { $this->team = session('currentTeam'); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Team/Invitations.php b/app/Http/Livewire/Team/Invitations.php index e61aca0e7..ba0b654aa 100644 --- a/app/Http/Livewire/Team/Invitations.php +++ b/app/Http/Livewire/Team/Invitations.php @@ -9,13 +9,15 @@ class Invitations extends Component { public $invitations; protected $listeners = ['refreshInvitations']; - public function refreshInvitations() - { - $this->invitations = TeamInvitation::whereTeamId(auth()->user()->currentTeam()->id)->get(); - } + public function deleteInvitation(int $invitation_id) { TeamInvitation::find($invitation_id)->delete(); $this->refreshInvitations(); } + + public function refreshInvitations() + { + $this->invitations = TeamInvitation::whereTeamId(auth()->user()->currentTeam()->id)->get(); + } } diff --git a/app/Http/Livewire/Team/InviteLink.php b/app/Http/Livewire/Team/InviteLink.php index b197334cb..66a8add4e 100644 --- a/app/Http/Livewire/Team/InviteLink.php +++ b/app/Http/Livewire/Team/InviteLink.php @@ -12,14 +12,17 @@ class InviteLink extends Component { public string $email; public string $role = 'member'; + public function mount() { $this->email = isDev() ? 'test3@example.com' : ''; } + public function viaEmail() { $this->generate_invite_link(isEmail: true); } + private function generate_invite_link(bool $isEmail = false) { try { @@ -72,8 +75,9 @@ private function generate_invite_link(bool $isEmail = false) return general_error_handler(err: $e, that: $this, customErrorMessage: $error_message); } } + public function viaLink() { $this->generate_invite_link(); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Team/Member.php b/app/Http/Livewire/Team/Member.php index 5f037e444..c356de75d 100644 --- a/app/Http/Livewire/Team/Member.php +++ b/app/Http/Livewire/Team/Member.php @@ -8,16 +8,19 @@ class Member extends Component { public User $member; + public function makeAdmin() { $this->member->teams()->updateExistingPivot(session('currentTeam')->id, ['role' => 'admin']); $this->emit('reloadWindow'); } + public function makeReadonly() { $this->member->teams()->updateExistingPivot(session('currentTeam')->id, ['role' => 'member']); $this->emit('reloadWindow'); } + public function remove() { $this->member->teams()->detach(session('currentTeam')); diff --git a/app/Http/Livewire/Team/Storage/Create.php b/app/Http/Livewire/Team/Storage/Create.php index 997b95015..38aee59b5 100644 --- a/app/Http/Livewire/Team/Storage/Create.php +++ b/app/Http/Livewire/Team/Storage/Create.php @@ -2,8 +2,8 @@ namespace App\Http\Livewire\Team\Storage; -use Livewire\Component; use App\Models\S3Storage; +use Livewire\Component; class Create extends Component { @@ -33,7 +33,9 @@ class Create extends Component 'bucket' => 'Bucket', 'endpoint' => 'Endpoint', ]; - public function mount() { + + public function mount() + { if (isDev()) { $this->name = 'Local MinIO'; $this->description = 'Local MinIO'; @@ -43,15 +45,9 @@ public function mount() { $this->endpoint = 'http://coolify-minio:9000'; } } - private function test_s3_connection() { - try { - $this->storage->testConnection(); - return $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); - } catch(\Throwable $th) { - return general_error_handler($th, $this); - } - } - public function submit() { + + public function submit() + { try { $this->validate(); $this->storage = new S3Storage(); @@ -71,9 +67,19 @@ public function submit() { $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); $this->storage->save(); return redirect()->route('team.storages.show', $this->storage->uuid); - } catch(\Throwable $th) { + } catch (\Throwable $th) { return general_error_handler($th, $this); } } -} \ No newline at end of file + + private function test_s3_connection() + { + try { + $this->storage->testConnection(); + return $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); + } catch (\Throwable $th) { + return general_error_handler($th, $this); + } + } +} diff --git a/app/Http/Livewire/Team/Storage/Form.php b/app/Http/Livewire/Team/Storage/Form.php index bb106e378..3bdbbc508 100644 --- a/app/Http/Livewire/Team/Storage/Form.php +++ b/app/Http/Livewire/Team/Storage/Form.php @@ -2,8 +2,8 @@ namespace App\Http\Livewire\Team\Storage; -use Livewire\Component; use App\Models\S3Storage; +use Livewire\Component; class Form extends Component { @@ -26,22 +26,27 @@ class Form extends Component 'storage.bucket' => 'Bucket', 'storage.endpoint' => 'Endpoint', ]; - public function test_s3_connection() { + + public function test_s3_connection() + { try { $this->storage->testConnection(); return $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); - } catch(\Throwable $th) { + } catch (\Throwable $th) { return general_error_handler($th, $this); } } - public function delete() { + + public function delete() + { try { $this->storage->delete(); return redirect()->route('team.storages.all'); - } catch(\Throwable $th) { + } catch (\Throwable $th) { return general_error_handler($th, $this); } } + public function submit() { $this->validate(); @@ -54,4 +59,4 @@ public function submit() return general_error_handler($th, $this); } } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Upgrade.php b/app/Http/Livewire/Upgrade.php index 8bd647f1d..e79c73fb7 100644 --- a/app/Http/Livewire/Upgrade.php +++ b/app/Http/Livewire/Upgrade.php @@ -4,8 +4,8 @@ use App\Actions\Server\UpdateCoolify; use App\Models\InstanceSettings; -use Masmerise\Toaster\Toaster; use Livewire\Component; +use Masmerise\Toaster\Toaster; class Upgrade extends Component { @@ -27,6 +27,7 @@ public function checkUpdate() $this->latestVersion = 'next'; } } + public function upgrade() { try { @@ -40,4 +41,4 @@ public function upgrade() return general_error_handler(err: $e, that: $this); } } -} \ No newline at end of file +} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index afc78c4e5..dae8398b7 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -13,7 +13,7 @@ class RedirectIfAuthenticated /** * Handle an incoming request. * - * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next + * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next, string ...$guards): Response { diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index c80ad531b..559dd2fc3 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -20,7 +20,7 @@ class TrustProxies extends Middleware * @var int */ protected $headers = - Request::HEADER_X_FORWARDED_FOR | + Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 945de85cb..2151219af 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -12,8 +12,8 @@ use App\Models\Server; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; -use App\Notifications\Application\DeploymentSuccess; use App\Notifications\Application\DeploymentFailed; +use App\Notifications\Application\DeploymentSuccess; use App\Traits\ExecuteRemoteCommand; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -22,8 +22,8 @@ use Illuminate\Queue\SerializesModels; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Storage; -use Spatie\Url\Url; use Illuminate\Support\Str; +use Spatie\Url\Url; use Symfony\Component\Yaml\Yaml; use Throwable; use Visus\Cuid2\Cuid2; @@ -61,6 +61,7 @@ class ApplicationDeploymentJob implements ShouldQueue private $log_model; private Collection $saved_outputs; + public function __construct(int $application_deployment_queue_id) { ray()->clearScreen(); @@ -137,62 +138,7 @@ public function handle(): void // ray()->measure(); } } - public function failed(Throwable $exception): void - { - $this->execute_remote_command( - ["echo 'Oops something is not okay, are you okay? 😢'"], - ["echo '{$exception->getMessage()}'"] - ); - $this->next(ApplicationDeploymentStatus::FAILED->value); - } - private function execute_in_builder(string $command) - { - return "docker exec {$this->deployment_uuid} bash -c '{$command}'"; - // return "docker exec {$this->deployment_uuid} bash -c '{$command} |& tee -a /proc/1/fd/1; [ \$PIPESTATUS -eq 0 ] || exit \$PIPESTATUS'"; - } - private function deploy() - { - $this->execute_remote_command( - [ - "echo 'Starting deployment of {$this->application->git_repository}:{$this->application->git_branch}.'" - ], - ); - $this->prepare_builder_image(); - $this->clone_repository(); - - $tag = Str::of("{$this->commit}-{$this->application->id}-{$this->pull_request_id}"); - if (strlen($tag) > 128) { - $tag = $tag->substr(0, 128); - }; - - $this->build_image_name = "{$this->application->git_repository}:{$tag}-build"; - $this->production_image_name = "{$this->application->uuid}:{$tag}"; - ray('Build Image Name: ' . $this->build_image_name . ' & Production Image Name: ' . $this->production_image_name)->green(); - - if (!$this->force_rebuild) { - $this->execute_remote_command([ - "docker images -q {$this->production_image_name} 2>/dev/null", "hidden" => true, "save" => "local_image_found" - ]); - if (Str::of($this->saved_outputs->get('local_image_found'))->isNotEmpty()) { - $this->execute_remote_command([ - "echo 'Docker Image found locally with the same Git Commit SHA {$this->application->uuid}:{$this->commit}. Build step skipped...'" - ]); - $this->generate_compose_file(); - $this->stop_running_container(); - $this->start_by_compose_file(); - return; - } - } - $this->cleanup_git(); - $this->generate_buildpack(); - $this->generate_compose_file(); - $this->generate_build_env_variables(); - $this->add_build_env_variables_to_dockerfile(); - $this->build_image(); - $this->stop_running_container(); - $this->start_by_compose_file(); - } private function deploy_pull_request() { $this->build_image_name = "{$this->application->uuid}:pr-{$this->pull_request_id}-build"; @@ -214,117 +160,154 @@ private function deploy_pull_request() $this->start_by_compose_file(); } - private function next(string $status) - { - // If the deployment is cancelled by the user, don't update the status - if ($this->application_deployment_queue->status !== ApplicationDeploymentStatus::CANCELLED_BY_USER->value) { - $this->application_deployment_queue->update([ - 'status' => $status, - ]); - } - queue_next_deployment($this->application); - if ($status === ApplicationDeploymentStatus::FINISHED->value) { - $this->application->environment->project->team->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview)); - } - if ($status === ApplicationDeploymentStatus::FAILED->value) { - $this->application->environment->project->team->notify(new DeploymentFailed($this->application, $this->deployment_uuid, $this->preview)); - } - } - private function start_by_compose_file() + private function prepare_builder_image() { $this->execute_remote_command( - ["echo -n 'Starting new application... '"], - [$this->execute_in_builder("docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true], - ["echo 'Done. 🎉'"], + [ + "echo -n 'Pulling latest version of the builder image (ghcr.io/coollabsio/coolify-builder).'", + ], + [ + "docker run --pull=always -d --name {$this->deployment_uuid} --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/coollabsio/coolify-builder", + "hidden" => true, + ], + [ + "command" => $this->execute_in_builder("mkdir -p {$this->workdir}") + ], ); } - private function stop_running_container() + + private function execute_in_builder(string $command) + { + return "docker exec {$this->deployment_uuid} bash -c '{$command}'"; + // return "docker exec {$this->deployment_uuid} bash -c '{$command} |& tee -a /proc/1/fd/1; [ \$PIPESTATUS -eq 0 ] || exit \$PIPESTATUS'"; + } + + private function clone_repository() { $this->execute_remote_command( - ["echo -n 'Removing old running application.'"], - [$this->execute_in_builder("docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true], + [ + "echo -n 'Importing {$this->application->git_repository}:{$this->application->git_branch} to {$this->workdir}. '" + ], + [ + $this->importing_git_repository() + ], + [ + $this->execute_in_builder("cd {$this->workdir} && git rev-parse HEAD"), + "hidden" => true, + "save" => "git_commit_sha" + ], + ); + $this->commit = $this->saved_outputs->get('git_commit_sha'); + } + + private function importing_git_repository() + { + $commands = collect([]); + $git_clone_command = "git clone -q -b {$this->application->git_branch}"; + if ($this->pull_request_id !== 0) { + $pr_branch_name = "pr-{$this->pull_request_id}-coolify"; + } + + if ($this->application->deploymentType() === 'source') { + $source_html_url = data_get($this->application, 'source.html_url'); + $url = parse_url(filter_var($source_html_url, FILTER_SANITIZE_URL)); + $source_html_url_host = $url['host']; + $source_html_url_scheme = $url['scheme']; + + if ($this->source->getMorphClass() == 'App\Models\GithubApp') { + if ($this->source->is_public) { + $git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}"; + $git_clone_command = $this->set_git_import_settings($git_clone_command); + + $commands->push($this->execute_in_builder($git_clone_command)); + } else { + $github_access_token = generate_github_installation_token($this->source); + $commands->push($this->execute_in_builder("git clone -q -b {$this->application->git_branch} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$this->application->git_repository}.git {$this->workdir}")); + } + if ($this->pull_request_id !== 0) { + $commands->push($this->execute_in_builder("cd {$this->workdir} && git fetch origin pull/{$this->pull_request_id}/head:$pr_branch_name && git checkout $pr_branch_name")); + } + return $commands->implode(' && '); + } + } + if ($this->application->deploymentType() === 'deploy_key') { + $private_key = base64_encode($this->application->private_key->private_key); + $git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_full_url} {$this->workdir}"; + $git_clone_command = $this->set_git_import_settings($git_clone_command); + $commands = collect([ + $this->execute_in_builder("mkdir -p /root/.ssh"), + $this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"), + $this->execute_in_builder("chmod 600 /root/.ssh/id_rsa"), + $this->execute_in_builder($git_clone_command) + ]); + return $commands->implode(' && '); + } + } + + private function set_git_import_settings($git_clone_command) + { + if ($this->application->git_commit_sha !== 'HEAD') { + $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git -c advice.detachedHead=false checkout {$this->application->git_commit_sha} >/dev/null 2>&1"; + } + if ($this->application->settings->is_git_submodules_enabled) { + $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git submodule update --init --recursive"; + } + if ($this->application->settings->is_git_lfs_enabled) { + $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git lfs pull"; + } + return $git_clone_command; + } + + private function cleanup_git() + { + $this->execute_remote_command( + [$this->execute_in_builder("rm -fr {$this->workdir}/.git")], ); } - private function build_image() + + private function generate_buildpack() { - $this->execute_remote_command([ - "echo -n 'Building docker image.'", - ]); - - if ($this->application->settings->is_static) { - $this->execute_remote_command([ - $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true - ]); - - $dockerfile = base64_encode("FROM {$this->application->static_image} -WORKDIR /usr/share/nginx/html/ -LABEL coolify.deploymentId={$this->deployment_uuid} -COPY --from=$this->build_image_name /app/{$this->application->publish_directory} . -COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); - - $nginx_config = base64_encode("server { - listen 80; - listen [::]:80; - server_name localhost; - - location / { - root /usr/share/nginx/html; - index index.html; - try_files \$uri \$uri.html \$uri/index.html \$uri/ /index.html =404; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - }"); - $this->execute_remote_command( - [ - $this->execute_in_builder("echo '{$dockerfile}' | base64 -d > {$this->workdir}/Dockerfile-prod") - ], - [ - $this->execute_in_builder("echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf") - ], - [ - $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile-prod {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true - ] - ); - } else { - $this->execute_remote_command([ - $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true - ]); - } + $this->execute_remote_command( + [ + "echo -n 'Generating nixpacks configuration.'", + ], + [$this->nixpacks_build_cmd()], + [$this->execute_in_builder("cp {$this->workdir}/.nixpacks/Dockerfile {$this->workdir}/Dockerfile")], + [$this->execute_in_builder("rm -f {$this->workdir}/.nixpacks/Dockerfile")] + ); } - private function add_build_env_variables_to_dockerfile() - { - $this->execute_remote_command([ - $this->execute_in_builder("cat {$this->workdir}/Dockerfile"), "hidden" => true, "save" => 'dockerfile' - ]); - $dockerfile = collect(Str::of($this->saved_outputs->get('dockerfile'))->trim()->explode("\n")); - foreach ($this->application->build_environment_variables as $env) { - $dockerfile->splice(1, 0, "ARG {$env->key}={$env->value}"); - } - $dockerfile_base64 = base64_encode($dockerfile->implode("\n")); - $this->execute_remote_command([ - $this->execute_in_builder("echo '{$dockerfile_base64}' | base64 -d > {$this->workdir}/Dockerfile"), - "hidden" => true - ]); - } - private function generate_build_env_variables() + private function nixpacks_build_cmd() { - $this->build_args = collect(["--build-arg SOURCE_COMMIT={$this->commit}"]); + $this->generate_env_variables(); + $nixpacks_command = "nixpacks build -o {$this->workdir} {$this->env_args} --no-error-without-start"; + if ($this->application->build_command) { + $nixpacks_command .= " --build-cmd \"{$this->application->build_command}\""; + } + if ($this->application->start_command) { + $nixpacks_command .= " --start-cmd \"{$this->application->start_command}\""; + } + if ($this->application->install_command) { + $nixpacks_command .= " --install-cmd \"{$this->application->install_command}\""; + } + $nixpacks_command .= " {$this->workdir}"; + return $this->execute_in_builder($nixpacks_command); + } + + private function generate_env_variables() + { + $this->env_args = collect([]); if ($this->pull_request_id === 0) { - foreach ($this->application->build_environment_variables as $env) { - $this->build_args->push("--build-arg {$env->key}={$env->value}"); + foreach ($this->application->nixpacks_environment_variables as $env) { + $this->env_args->push("--env {$env->key}={$env->value}"); } } else { - foreach ($this->application->build_environment_variables_preview as $env) { - $this->build_args->push("--build-arg {$env->key}={$env->value}"); + foreach ($this->application->nixpacks_environment_variables_preview as $env) { + $this->env_args->push("--env {$env->key}={$env->value}"); } } - $this->build_args = $this->build_args->implode(' '); + $this->env_args = $this->env_args->implode(' '); } private function generate_compose_file() @@ -388,6 +371,7 @@ private function generate_compose_file() $docker_compose_base64 = base64_encode($this->docker_compose); $this->execute_remote_command([$this->execute_in_builder("echo '{$docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml"), "hidden" => true]); } + private function generate_local_persistent_volumes() { $local_persistent_volumes = []; @@ -400,6 +384,7 @@ private function generate_local_persistent_volumes() } return $local_persistent_volumes; } + private function generate_local_persistent_volumes_only_volume_names() { $local_persistent_volumes_names = []; @@ -420,6 +405,7 @@ private function generate_local_persistent_volumes_only_volume_names() } return $local_persistent_volumes_names; } + private function generate_environment_variables($ports) { $environment_variables = collect(); @@ -436,27 +422,12 @@ private function generate_environment_variables($ports) } } // Add PORT if not exists, use the first port as default - if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('PORT'))->isEmpty()) { + if ($environment_variables->filter(fn($env) => Str::of($env)->contains('PORT'))->isEmpty()) { $environment_variables->push("PORT={$ports[0]}"); } return $environment_variables->all(); } - private function generate_healthcheck_commands() - { - if (!$this->application->health_check_port) { - $this->application->health_check_port = $this->application->ports_exposes_array[0]; - } - if ($this->application->health_check_path) { - $generated_healthchecks_commands = [ - "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$this->application->health_check_port}{$this->application->health_check_path} > /dev/null" - ]; - } else { - $generated_healthchecks_commands = [ - "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$this->application->health_check_port}/" - ]; - } - return implode(' ', $generated_healthchecks_commands); - } + private function set_labels_for_applications() { $labels = []; @@ -520,140 +491,192 @@ private function set_labels_for_applications() } return $labels; } - private function generate_buildpack() + + private function generate_healthcheck_commands() + { + if (!$this->application->health_check_port) { + $this->application->health_check_port = $this->application->ports_exposes_array[0]; + } + if ($this->application->health_check_path) { + $generated_healthchecks_commands = [ + "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$this->application->health_check_port}{$this->application->health_check_path} > /dev/null" + ]; + } else { + $generated_healthchecks_commands = [ + "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$this->application->health_check_port}/" + ]; + } + return implode(' ', $generated_healthchecks_commands); + } + + private function build_image() + { + $this->execute_remote_command([ + "echo -n 'Building docker image.'", + ]); + + if ($this->application->settings->is_static) { + $this->execute_remote_command([ + $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true + ]); + + $dockerfile = base64_encode("FROM {$this->application->static_image} +WORKDIR /usr/share/nginx/html/ +LABEL coolify.deploymentId={$this->deployment_uuid} +COPY --from=$this->build_image_name /app/{$this->application->publish_directory} . +COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); + + $nginx_config = base64_encode("server { + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html; + try_files \$uri \$uri.html \$uri/index.html \$uri/ /index.html =404; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + }"); + $this->execute_remote_command( + [ + $this->execute_in_builder("echo '{$dockerfile}' | base64 -d > {$this->workdir}/Dockerfile-prod") + ], + [ + $this->execute_in_builder("echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf") + ], + [ + $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile-prod {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true + ] + ); + } else { + $this->execute_remote_command([ + $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true + ]); + } + } + + private function stop_running_container() { $this->execute_remote_command( - [ - "echo -n 'Generating nixpacks configuration.'", - ], - [$this->nixpacks_build_cmd()], - [$this->execute_in_builder("cp {$this->workdir}/.nixpacks/Dockerfile {$this->workdir}/Dockerfile")], - [$this->execute_in_builder("rm -f {$this->workdir}/.nixpacks/Dockerfile")] + ["echo -n 'Removing old running application.'"], + [$this->execute_in_builder("docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true], ); } - private function nixpacks_build_cmd() + + private function start_by_compose_file() { - $this->generate_env_variables(); - $nixpacks_command = "nixpacks build -o {$this->workdir} {$this->env_args} --no-error-without-start"; - if ($this->application->build_command) { - $nixpacks_command .= " --build-cmd \"{$this->application->build_command}\""; - } - if ($this->application->start_command) { - $nixpacks_command .= " --start-cmd \"{$this->application->start_command}\""; - } - if ($this->application->install_command) { - $nixpacks_command .= " --install-cmd \"{$this->application->install_command}\""; - } - $nixpacks_command .= " {$this->workdir}"; - return $this->execute_in_builder($nixpacks_command); + $this->execute_remote_command( + ["echo -n 'Starting new application... '"], + [$this->execute_in_builder("docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true], + ["echo 'Done. 🎉'"], + ); } - private function generate_env_variables() + + private function deploy() { - $this->env_args = collect([]); + + $this->execute_remote_command( + [ + "echo 'Starting deployment of {$this->application->git_repository}:{$this->application->git_branch}.'" + ], + ); + $this->prepare_builder_image(); + $this->clone_repository(); + + $tag = Str::of("{$this->commit}-{$this->application->id}-{$this->pull_request_id}"); + if (strlen($tag) > 128) { + $tag = $tag->substr(0, 128); + }; + + $this->build_image_name = "{$this->application->git_repository}:{$tag}-build"; + $this->production_image_name = "{$this->application->uuid}:{$tag}"; + ray('Build Image Name: ' . $this->build_image_name . ' & Production Image Name: ' . $this->production_image_name)->green(); + + if (!$this->force_rebuild) { + $this->execute_remote_command([ + "docker images -q {$this->production_image_name} 2>/dev/null", "hidden" => true, "save" => "local_image_found" + ]); + if (Str::of($this->saved_outputs->get('local_image_found'))->isNotEmpty()) { + $this->execute_remote_command([ + "echo 'Docker Image found locally with the same Git Commit SHA {$this->application->uuid}:{$this->commit}. Build step skipped...'" + ]); + $this->generate_compose_file(); + $this->stop_running_container(); + $this->start_by_compose_file(); + return; + } + } + $this->cleanup_git(); + $this->generate_buildpack(); + $this->generate_compose_file(); + $this->generate_build_env_variables(); + $this->add_build_env_variables_to_dockerfile(); + $this->build_image(); + $this->stop_running_container(); + $this->start_by_compose_file(); + } + + private function generate_build_env_variables() + { + $this->build_args = collect(["--build-arg SOURCE_COMMIT={$this->commit}"]); if ($this->pull_request_id === 0) { - foreach ($this->application->nixpacks_environment_variables as $env) { - $this->env_args->push("--env {$env->key}={$env->value}"); + foreach ($this->application->build_environment_variables as $env) { + $this->build_args->push("--build-arg {$env->key}={$env->value}"); } } else { - foreach ($this->application->nixpacks_environment_variables_preview as $env) { - $this->env_args->push("--env {$env->key}={$env->value}"); + foreach ($this->application->build_environment_variables_preview as $env) { + $this->build_args->push("--build-arg {$env->key}={$env->value}"); } } - $this->env_args = $this->env_args->implode(' '); + $this->build_args = $this->build_args->implode(' '); } - private function cleanup_git() - { - $this->execute_remote_command( - [$this->execute_in_builder("rm -fr {$this->workdir}/.git")], - ); - } - private function prepare_builder_image() - { - $this->execute_remote_command( - [ - "echo -n 'Pulling latest version of the builder image (ghcr.io/coollabsio/coolify-builder).'", - ], - [ - "docker run --pull=always -d --name {$this->deployment_uuid} --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/coollabsio/coolify-builder", - "hidden" => true, - ], - [ - "command" => $this->execute_in_builder("mkdir -p {$this->workdir}") - ], - ); - } - private function set_git_import_settings($git_clone_command) - { - if ($this->application->git_commit_sha !== 'HEAD') { - $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git -c advice.detachedHead=false checkout {$this->application->git_commit_sha} >/dev/null 2>&1"; - } - if ($this->application->settings->is_git_submodules_enabled) { - $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git submodule update --init --recursive"; - } - if ($this->application->settings->is_git_lfs_enabled) { - $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git lfs pull"; - } - return $git_clone_command; - } - private function importing_git_repository() - { - $commands = collect([]); - $git_clone_command = "git clone -q -b {$this->application->git_branch}"; - if ($this->pull_request_id !== 0) { - $pr_branch_name = "pr-{$this->pull_request_id}-coolify"; - } - if ($this->application->deploymentType() === 'source') { - $source_html_url = data_get($this->application, 'source.html_url'); - $url = parse_url(filter_var($source_html_url, FILTER_SANITIZE_URL)); - $source_html_url_host = $url['host']; - $source_html_url_scheme = $url['scheme']; + private function add_build_env_variables_to_dockerfile() + { + $this->execute_remote_command([ + $this->execute_in_builder("cat {$this->workdir}/Dockerfile"), "hidden" => true, "save" => 'dockerfile' + ]); + $dockerfile = collect(Str::of($this->saved_outputs->get('dockerfile'))->trim()->explode("\n")); - if ($this->source->getMorphClass() == 'App\Models\GithubApp') { - if ($this->source->is_public) { - $git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}"; - $git_clone_command = $this->set_git_import_settings($git_clone_command); - - $commands->push($this->execute_in_builder($git_clone_command)); - } else { - $github_access_token = generate_github_installation_token($this->source); - $commands->push($this->execute_in_builder("git clone -q -b {$this->application->git_branch} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$this->application->git_repository}.git {$this->workdir}")); - } - if ($this->pull_request_id !== 0) { - $commands->push($this->execute_in_builder("cd {$this->workdir} && git fetch origin pull/{$this->pull_request_id}/head:$pr_branch_name && git checkout $pr_branch_name")); - } - return $commands->implode(' && '); - } + foreach ($this->application->build_environment_variables as $env) { + $dockerfile->splice(1, 0, "ARG {$env->key}={$env->value}"); } - if ($this->application->deploymentType() === 'deploy_key') { - $private_key = base64_encode($this->application->private_key->private_key); - $git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_full_url} {$this->workdir}"; - $git_clone_command = $this->set_git_import_settings($git_clone_command); - $commands = collect([ - $this->execute_in_builder("mkdir -p /root/.ssh"), - $this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"), - $this->execute_in_builder("chmod 600 /root/.ssh/id_rsa"), - $this->execute_in_builder($git_clone_command) + $dockerfile_base64 = base64_encode($dockerfile->implode("\n")); + $this->execute_remote_command([ + $this->execute_in_builder("echo '{$dockerfile_base64}' | base64 -d > {$this->workdir}/Dockerfile"), + "hidden" => true + ]); + } + + private function next(string $status) + { + // If the deployment is cancelled by the user, don't update the status + if ($this->application_deployment_queue->status !== ApplicationDeploymentStatus::CANCELLED_BY_USER->value) { + $this->application_deployment_queue->update([ + 'status' => $status, ]); - return $commands->implode(' && '); + } + queue_next_deployment($this->application); + if ($status === ApplicationDeploymentStatus::FINISHED->value) { + $this->application->environment->project->team->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview)); + } + if ($status === ApplicationDeploymentStatus::FAILED->value) { + $this->application->environment->project->team->notify(new DeploymentFailed($this->application, $this->deployment_uuid, $this->preview)); } } - private function clone_repository() + + public function failed(Throwable $exception): void { $this->execute_remote_command( - [ - "echo -n 'Importing {$this->application->git_repository}:{$this->application->git_branch} to {$this->workdir}. '" - ], - [ - $this->importing_git_repository() - ], - [ - $this->execute_in_builder("cd {$this->workdir} && git rev-parse HEAD"), - "hidden" => true, - "save" => "git_commit_sha" - ], + ["echo 'Oops something is not okay, are you okay? 😢'"], + ["echo '{$exception->getMessage()}'"] ); - $this->commit = $this->saved_outputs->get('git_commit_sha'); + $this->next(ApplicationDeploymentStatus::FAILED->value); } -} \ No newline at end of file +} diff --git a/app/Jobs/ApplicationPullRequestUpdateJob.php b/app/Jobs/ApplicationPullRequestUpdateJob.php index e0f51e0ee..2b84cbe5a 100755 --- a/app/Jobs/ApplicationPullRequestUpdateJob.php +++ b/app/Jobs/ApplicationPullRequestUpdateJob.php @@ -22,11 +22,13 @@ class ApplicationPullRequestUpdateJob implements ShouldQueue public function __construct( public string $application_id, - public int $pull_request_id, + public int $pull_request_id, public string $deployment_uuid, public string $status - ) { + ) + { } + public function handle() { try { @@ -61,6 +63,7 @@ public function handle() throw $e; } } + private function update_comment() { ['data' => $data] = git_api(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/issues/comments/{$this->preview->pull_request_issue_comment_id}", method: 'patch', data: [ @@ -71,6 +74,7 @@ private function update_comment() $this->create_comment(); } } + private function create_comment() { ['data' => $data] = git_api(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/issues/{$this->pull_request_id}/comments", method: 'post', data: [ diff --git a/app/Jobs/CheckResaleLicenseJob.php b/app/Jobs/CheckResaleLicenseJob.php index 0e925c569..f14214733 100644 --- a/app/Jobs/CheckResaleLicenseJob.php +++ b/app/Jobs/CheckResaleLicenseJob.php @@ -3,15 +3,11 @@ namespace App\Jobs; use App\Actions\License\CheckResaleLicense; -use App\Models\InstanceSettings; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\Http; -use Visus\Cuid2\Cuid2; class CheckResaleLicenseJob implements ShouldQueue { diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 7db4dce72..083023929 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -2,7 +2,6 @@ namespace App\Jobs; -use App\Models\Application; use App\Models\ApplicationPreview; use App\Notifications\Application\StatusChanged; use Illuminate\Bus\Queueable; @@ -11,7 +10,6 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\Log; class ContainerStatusJob implements ShouldQueue, ShouldBeUnique { @@ -27,10 +25,12 @@ public function __construct($resource, string $container_name, string|null $pull $this->container_name = $container_name; $this->pull_request_id = $pull_request_id; } + public function uniqueId(): string { return $this->container_name; } + public function handle(): void { try { diff --git a/app/Jobs/CoolifyTask.php b/app/Jobs/CoolifyTask.php index d87468efc..10bc89358 100755 --- a/app/Jobs/CoolifyTask.php +++ b/app/Jobs/CoolifyTask.php @@ -19,8 +19,9 @@ class CoolifyTask implements ShouldQueue */ public function __construct( public Activity $activity, - public bool $ignore_errors = false, - ) { + public bool $ignore_errors = false, + ) + { } /** diff --git a/app/Jobs/DockerCleanupJob.php b/app/Jobs/DockerCleanupJob.php index 3eb1b939b..2c0a3fc06 100644 --- a/app/Jobs/DockerCleanupJob.php +++ b/app/Jobs/DockerCleanupJob.php @@ -8,13 +8,14 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; class DockerCleanupJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + public $timeout = 500; + /** * Create a new job instance. */ diff --git a/app/Jobs/InstanceApplicationsStatusJob.php b/app/Jobs/InstanceApplicationsStatusJob.php index a7ab592b0..fd173215b 100644 --- a/app/Jobs/InstanceApplicationsStatusJob.php +++ b/app/Jobs/InstanceApplicationsStatusJob.php @@ -15,10 +15,12 @@ class InstanceApplicationsStatusJob implements ShouldQueue, ShouldBeUnique use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public $applications; + public function __construct() { $this->applications = Application::all(); } + public function handle(): void { try { diff --git a/app/Jobs/InstanceAutoUpdateJob.php b/app/Jobs/InstanceAutoUpdateJob.php index b0b19aef1..957b8fe23 100644 --- a/app/Jobs/InstanceAutoUpdateJob.php +++ b/app/Jobs/InstanceAutoUpdateJob.php @@ -3,9 +3,6 @@ namespace App\Jobs; use App\Actions\Server\UpdateCoolify; -use App\Models\InstanceSettings; -use App\Models\Server; -use Exception; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; @@ -22,6 +19,7 @@ class InstanceAutoUpdateJob implements ShouldQueue, ShouldBeUnique public function __construct(private bool $force = false) { } + public function handle(): void { resolve(UpdateCoolify::class)($this->force); diff --git a/app/Jobs/ProxyCheckJob.php b/app/Jobs/ProxyCheckJob.php index 87e7c9bda..7c498107d 100755 --- a/app/Jobs/ProxyCheckJob.php +++ b/app/Jobs/ProxyCheckJob.php @@ -3,7 +3,6 @@ namespace App\Jobs; use App\Actions\Proxy\StartProxy; -use App\Enums\ProxyTypes; use App\Models\Server; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -18,6 +17,7 @@ class ProxyCheckJob implements ShouldQueue public function __construct() { } + public function handle() { try { diff --git a/app/Jobs/ProxyContainerStatusJob.php b/app/Jobs/ProxyContainerStatusJob.php index 02cd37568..68372895a 100644 --- a/app/Jobs/ProxyContainerStatusJob.php +++ b/app/Jobs/ProxyContainerStatusJob.php @@ -9,8 +9,8 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Queue\SerializesModels; use Illuminate\Queue\Middleware\WithoutOverlapping; +use Illuminate\Queue\SerializesModels; use Illuminate\Support\Str; class ProxyContainerStatusJob implements ShouldQueue, ShouldBeUnique @@ -20,18 +20,22 @@ class ProxyContainerStatusJob implements ShouldQueue, ShouldBeUnique public Server $server; public $tries = 1; public $timeout = 120; - public function middleware(): array - { - return [new WithoutOverlapping($this->server->id)]; - } + public function __construct(Server $server) { $this->server = $server; } + + public function middleware(): array + { + return [new WithoutOverlapping($this->server->id)]; + } + public function uniqueId(): int { return $this->server->id; } + public function handle(): void { try { diff --git a/app/Jobs/ProxyStartJob.php b/app/Jobs/ProxyStartJob.php index 074d21664..5119210fc 100755 --- a/app/Jobs/ProxyStartJob.php +++ b/app/Jobs/ProxyStartJob.php @@ -17,6 +17,7 @@ class ProxyStartJob implements ShouldQueue public function __construct(protected Server $server) { } + public function handle() { try { diff --git a/app/Jobs/SendMessageToDiscordJob.php b/app/Jobs/SendMessageToDiscordJob.php index 11122e7e3..577b3a907 100644 --- a/app/Jobs/SendMessageToDiscordJob.php +++ b/app/Jobs/SendMessageToDiscordJob.php @@ -3,7 +3,6 @@ namespace App\Jobs; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; @@ -29,7 +28,8 @@ class SendMessageToDiscordJob implements ShouldQueue public function __construct( public string $text, public string $webhookUrl - ) { + ) + { } /** diff --git a/app/Models/Application.php b/app/Models/Application.php index 2c395511b..664b695b6 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -2,28 +2,12 @@ namespace App\Models; -use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; -use Spatie\Activitylog\Models\Activity; use Illuminate\Database\Eloquent\Relations\HasMany; -use Masmerise\Toaster\Toastable; -use Masmerise\Toaster\Toaster; -use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; +use Spatie\Activitylog\Models\Activity; class Application extends BaseModel { - protected static function booted() - { - static::created(function ($application) { - ApplicationSetting::create([ - 'application_id' => $application->id, - ]); - }); - static::deleting(function ($application) { - $application->settings()->delete(); - $application->persistentStorages()->delete(); - }); - } protected $fillable = [ 'name', 'repository_project_id', @@ -43,15 +27,42 @@ protected static function booted() 'publish_directory', 'private_key_id' ]; - public function type() { + + protected static function booted() + { + static::created(function ($application) { + ApplicationSetting::create([ + 'application_id' => $application->id, + ]); + }); + static::deleting(function ($application) { + $application->settings()->delete(); + $application->persistentStorages()->delete(); + }); + } + + public function settings() + { + return $this->hasOne(ApplicationSetting::class); + } + + public function persistentStorages() + { + return $this->morphMany(LocalPersistentVolume::class, 'resource'); + } + + public function type() + { return 'application'; } + public function publishDirectory(): Attribute { return Attribute::make( - set: fn ($value) => $value ? '/' . ltrim($value, '/') : null, + set: fn($value) => $value ? '/' . ltrim($value, '/') : null, ); } + public function gitBranchLocation(): Attribute { return Attribute::make( @@ -63,6 +74,7 @@ public function gitBranchLocation(): Attribute ); } + public function gitCommits(): Attribute { return Attribute::make( @@ -73,99 +85,108 @@ public function gitCommits(): Attribute } ); } + public function baseDirectory(): Attribute { return Attribute::make( - set: fn ($value) => '/' . ltrim($value, '/'), + set: fn($value) => '/' . ltrim($value, '/'), ); } + public function portsMappings(): Attribute { return Attribute::make( - set: fn ($value) => $value === "" ? null : $value, + set: fn($value) => $value === "" ? null : $value, ); } + + // Normal Deployments + public function portsMappingsArray(): Attribute { return Attribute::make( - get: fn () => - is_null($this->ports_mappings) + get: fn() => is_null($this->ports_mappings) ? [] : explode(',', $this->ports_mappings), ); } + public function portsExposesArray(): Attribute { return Attribute::make( - get: fn () => - is_null($this->ports_exposes) + get: fn() => is_null($this->ports_exposes) ? [] : explode(',', $this->ports_exposes) ); } - // Normal Deployments + public function environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false); } + public function runtime_environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('key', 'not like', 'NIXPACKS_%'); } + + // Preview Deployments + public function build_environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('is_build_time', true)->where('key', 'not like', 'NIXPACKS_%'); } + public function nixpacks_environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('key', 'like', 'NIXPACKS_%'); } - // Preview Deployments + public function environment_variables_preview(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true); } + public function runtime_environment_variables_preview(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('key', 'not like', 'NIXPACKS_%'); } + public function build_environment_variables_preview(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('is_build_time', true)->where('key', 'not like', 'NIXPACKS_%'); } + public function nixpacks_environment_variables_preview(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('key', 'like', 'NIXPACKS_%'); } + public function private_key() { return $this->belongsTo(PrivateKey::class); } + public function environment() { return $this->belongsTo(Environment::class); } + public function previews() { return $this->hasMany(ApplicationPreview::class); } - public function settings() - { - return $this->hasOne(ApplicationSetting::class); - } + public function destination() { return $this->morphTo(); } + public function source() { return $this->morphTo(); } - public function persistentStorages() - { - return $this->morphMany(LocalPersistentVolume::class, 'resource'); - } public function deployments(int $skip = 0, int $take = 10) { @@ -177,10 +198,12 @@ public function deployments(int $skip = 0, int $take = 10) 'deployments' => $deployments ]; } + public function get_deployment(string $deployment_uuid) { return Activity::where('subject_id', $this->id)->where('properties->type_uuid', '=', $deployment_uuid)->first(); } + public function isDeployable(): bool { if ($this->settings->is_auto_deploy_enabled) { @@ -188,6 +211,7 @@ public function isDeployable(): bool } return false; } + public function isPRDeployable(): bool { if ($this->settings->is_preview_deployments_enabled) { @@ -195,6 +219,7 @@ public function isPRDeployable(): bool } return false; } + public function deploymentType() { if (data_get($this, 'private_key_id')) { diff --git a/app/Models/ApplicationPreview.php b/app/Models/ApplicationPreview.php index 910e9b73b..38ac5127d 100644 --- a/app/Models/ApplicationPreview.php +++ b/app/Models/ApplicationPreview.php @@ -13,12 +13,14 @@ class ApplicationPreview extends BaseModel 'status', 'application_id', ]; - public function application() - { - return $this->belongsTo(Application::class); - } + static function findPreviewByApplicationAndPullId(int $application_id, int $pull_request_id) { return self::where('application_id', $application_id)->where('pull_request_id', $pull_request_id)->firstOrFail(); } + + public function application() + { + return $this->belongsTo(Application::class); + } } diff --git a/app/Models/ApplicationSetting.php b/app/Models/ApplicationSetting.php index 3bdd6a7cd..1340c8fa0 100644 --- a/app/Models/ApplicationSetting.php +++ b/app/Models/ApplicationSetting.php @@ -26,6 +26,7 @@ class ApplicationSetting extends Model 'is_git_submodules_enabled', 'is_git_lfs_enabled', ]; + public function isStatic(): Attribute { return Attribute::make( @@ -42,6 +43,7 @@ public function isStatic(): Attribute } ); } + public function application() { return $this->belongsTo(Application::class); diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php index 8f2ee86ae..be487a497 100644 --- a/app/Models/BaseModel.php +++ b/app/Models/BaseModel.php @@ -14,7 +14,7 @@ protected static function boot() static::creating(function (Model $model) { // Generate a UUID if one isn't set if (!$model->uuid) { - $model->uuid = (string) new Cuid2(7); + $model->uuid = (string)new Cuid2(7); } }); } diff --git a/app/Models/Database.php b/app/Models/Database.php index ab0476d27..85434feea 100644 --- a/app/Models/Database.php +++ b/app/Models/Database.php @@ -8,6 +8,7 @@ public function environment() { return $this->belongsTo(Environment::class); } + public function destination() { return $this->morphTo(); diff --git a/app/Models/Environment.php b/app/Models/Environment.php index 3f8940cde..458223ac9 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -11,32 +11,41 @@ class Environment extends Model 'name', 'project_id', ]; - protected function name(): Attribute + + public function can_delete_environment() { - return Attribute::make( - set: fn (string $value) => strtolower($value), - ); - } - public function can_delete_environment() { return $this->applications()->count() == 0 && $this->postgresqls()->count() == 0; } - public function databases() { - return $this->postgresqls(); - } - public function project() - { - return $this->belongsTo(Project::class); - } + public function applications() { return $this->hasMany(Application::class); } + public function postgresqls() { return $this->hasMany(StandalonePostgresql::class); } + + public function databases() + { + return $this->postgresqls(); + } + + public function project() + { + return $this->belongsTo(Project::class); + } + public function services() { return $this->hasMany(Service::class); } + + protected function name(): Attribute + { + return Attribute::make( + set: fn(string $value) => strtolower($value), + ); + } } diff --git a/app/Models/EnvironmentVariable.php b/app/Models/EnvironmentVariable.php index f3be6716b..23a420ef5 100644 --- a/app/Models/EnvironmentVariable.php +++ b/app/Models/EnvironmentVariable.php @@ -15,21 +15,30 @@ class EnvironmentVariable extends Model 'value' => 'encrypted', 'is_build_time' => 'boolean', ]; + protected static function booted() { static::created(function ($environment_variable) { - if ($environment_variable->application_id && !$environment_variable->is_preview) { - ModelsEnvironmentVariable::create([ - 'key' => $environment_variable->key, - 'value' => $environment_variable->value, - 'is_build_time' => $environment_variable->is_build_time, - 'application_id' => $environment_variable->application_id, - 'is_preview' => true, - ]); - } + if ($environment_variable->application_id && !$environment_variable->is_preview) { + ModelsEnvironmentVariable::create([ + 'key' => $environment_variable->key, + 'value' => $environment_variable->value, + 'is_build_time' => $environment_variable->is_build_time, + 'application_id' => $environment_variable->application_id, + 'is_preview' => true, + ]); + } }); } + protected function value(): Attribute + { + return Attribute::make( + get: fn(string $value) => $this->get_environment_variables($value), + set: fn(string $value) => $this->set_environment_variables($value), + ); + } + private function get_environment_variables(string $environment_variable): string|null { // $team_id = session('currentTeam')->id; @@ -45,6 +54,7 @@ private function get_environment_variables(string $environment_variable): string } return decrypt($environment_variable); } + private function set_environment_variables(string $environment_variable): string|null { $environment_variable = trim($environment_variable); @@ -53,17 +63,11 @@ private function set_environment_variables(string $environment_variable): string } return $environment_variable; } - protected function value(): Attribute - { - return Attribute::make( - get: fn (string $value) => $this->get_environment_variables($value), - set: fn (string $value) => $this->set_environment_variables($value), - ); - } + protected function key(): Attribute { return Attribute::make( - set: fn (string $value) => Str::of($value)->trim(), + set: fn(string $value) => Str::of($value)->trim(), ); } } diff --git a/app/Models/GithubApp.php b/app/Models/GithubApp.php index 54e68aa63..8db24b900 100644 --- a/app/Models/GithubApp.php +++ b/app/Models/GithubApp.php @@ -16,6 +16,17 @@ class GithubApp extends BaseModel 'client_secret', 'webhook_secret', ]; + + static public function public() + { + return GithubApp::whereTeamId(session('currentTeam')->id)->whereisPublic(true)->whereNotNull('app_id')->get(); + } + + static public function private() + { + return GithubApp::whereTeamId(session('currentTeam')->id)->whereisPublic(false)->whereNotNull('app_id')->get(); + } + protected static function booted(): void { static::deleting(function (GithubApp $github_app) { @@ -25,14 +36,17 @@ protected static function booted(): void } }); } + public function applications() { return $this->morphMany(Application::class, 'source'); } + public function privateKey() { return $this->belongsTo(PrivateKey::class); } + public function type(): Attribute { return Attribute::make( @@ -43,12 +57,4 @@ public function type(): Attribute }, ); } - static public function public() - { - return GithubApp::whereTeamId(session('currentTeam')->id)->whereisPublic(true)->whereNotNull('app_id')->get(); - } - static public function private() - { - return GithubApp::whereTeamId(session('currentTeam')->id)->whereisPublic(false)->whereNotNull('app_id')->get(); - } } diff --git a/app/Models/GitlabApp.php b/app/Models/GitlabApp.php index dbac3414b..a789a7e65 100644 --- a/app/Models/GitlabApp.php +++ b/app/Models/GitlabApp.php @@ -8,10 +8,12 @@ class GitlabApp extends BaseModel 'webhook_token', 'app_secret', ]; + public function applications() { return $this->morphMany(Application::class, 'source'); } + public function privateKey() { return $this->belongsTo(PrivateKey::class); diff --git a/app/Models/InstanceSettings.php b/app/Models/InstanceSettings.php index ef7859786..0fc892d92 100644 --- a/app/Models/InstanceSettings.php +++ b/app/Models/InstanceSettings.php @@ -3,28 +3,29 @@ namespace App\Models; use App\Notifications\Channels\SendsEmail; -use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; -use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; class InstanceSettings extends Model implements SendsEmail { use Notifiable; + protected $guarded = []; protected $casts = [ 'resale_license' => 'encrypted', ]; + + public static function get() + { + return InstanceSettings::findOrFail(0); + } + public function getRecepients($notification) { - $recipients = data_get($notification,'emails',null); + $recipients = data_get($notification, 'emails', null); if (is_null($recipients) || $recipients === '') { return []; } return explode(',', $recipients); } - public static function get() - { - return InstanceSettings::findOrFail(0); - } -} \ No newline at end of file +} diff --git a/app/Models/LocalPersistentVolume.php b/app/Models/LocalPersistentVolume.php index 71546df4d..68d6faded 100644 --- a/app/Models/LocalPersistentVolume.php +++ b/app/Models/LocalPersistentVolume.php @@ -9,26 +9,31 @@ class LocalPersistentVolume extends Model { protected $guarded = []; + public function application() { return $this->morphTo(); } + public function standalone_postgresql() { return $this->morphTo(); } + protected function name(): Attribute { return Attribute::make( - set: fn (string $value) => Str::of($value)->trim()->value, + set: fn(string $value) => Str::of($value)->trim()->value, ); } + protected function mountPath(): Attribute { return Attribute::make( - set: fn (string $value) => Str::of($value)->trim()->start('/')->value + set: fn(string $value) => Str::of($value)->trim()->start('/')->value ); } + protected function hostPath(): Attribute { return Attribute::make( diff --git a/app/Models/PrivateKey.php b/app/Models/PrivateKey.php index 82858ff22..795ede3b7 100644 --- a/app/Models/PrivateKey.php +++ b/app/Models/PrivateKey.php @@ -12,27 +12,13 @@ class PrivateKey extends BaseModel 'is_git_related', 'team_id', ]; + static public function ownedByCurrentTeam(array $select = ['*']) { $selectArray = collect($select)->concat(['id']); return PrivateKey::whereTeamId(session('currentTeam')->id)->select($selectArray->all()); } - public function applications() - { - return $this->hasMany(Application::class); - } - public function githubApps() - { - return $this->hasMany(GithubApp::class); - } - public function gitlabApps() - { - return $this->hasMany(GitlabApp::class); - } - public function servers() - { - return $this->hasMany(Server::class); - } + public function isEmpty() { if ($this->servers()->count() === 0 && $this->applications()->count() === 0 && $this->githubApps()->count() === 0 && $this->gitlabApps()->count() === 0) { @@ -40,4 +26,24 @@ public function isEmpty() } return false; } + + public function servers() + { + return $this->hasMany(Server::class); + } + + public function applications() + { + return $this->hasMany(Application::class); + } + + public function githubApps() + { + return $this->hasMany(GithubApp::class); + } + + public function gitlabApps() + { + return $this->hasMany(GitlabApp::class); + } } diff --git a/app/Models/Project.php b/app/Models/Project.php index dbba240af..55bc0a6cf 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -4,6 +4,18 @@ class Project extends BaseModel { + protected $fillable = [ + 'name', + 'description', + 'team_id', + 'project_id' + ]; + + static public function ownedByCurrentTeam() + { + return Project::whereTeamId(session('currentTeam')->id)->orderBy('name'); + } + protected static function booted() { static::created(function ($project) { @@ -20,32 +32,27 @@ protected static function booted() $project->settings()->delete(); }); } - protected $fillable = [ - 'name', - 'description', - 'team_id', - 'project_id' - ]; - static public function ownedByCurrentTeam() - { - return Project::whereTeamId(session('currentTeam')->id)->orderBy('name'); - } - public function team() - { - return $this->belongsTo(Team::class); - } + public function environments() { return $this->hasMany(Environment::class); } + public function settings() { return $this->hasOne(ProjectSetting::class); } + + public function team() + { + return $this->belongsTo(Team::class); + } + public function applications() { return $this->hasManyThrough(Application::class, Environment::class); } + public function postgresqls() { return $this->hasManyThrough(StandalonePostgresql::class, Environment::class); diff --git a/app/Models/S3Storage.php b/app/Models/S3Storage.php index a6f6360ac..754f53635 100644 --- a/app/Models/S3Storage.php +++ b/app/Models/S3Storage.php @@ -7,6 +7,7 @@ class S3Storage extends BaseModel { use HasFactory; + protected $guarded = []; protected $casts = [ 'key' => 'encrypted', @@ -18,12 +19,16 @@ static public function ownedByCurrentTeam(array $select = ['*']) $selectArray = collect($select)->concat(['id']); return S3Storage::whereTeamId(session('currentTeam')->id)->select($selectArray->all())->orderBy('name'); } - public function awsUrl() { + + public function awsUrl() + { return "{$this->endpoint}/{$this->bucket}"; } - public function testConnection() { + + public function testConnection() + { set_s3_target($this); return \Storage::disk('custom-s3')->files(); } -} \ No newline at end of file +} diff --git a/app/Models/Server.php b/app/Models/Server.php index 31e2d1e5c..5f24de02b 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -9,12 +9,47 @@ class Server extends BaseModel { use SchemalessAttributesTrait; - protected $schemalessAttributes = [ - 'proxy', - ]; + public $casts = [ 'proxy' => SchemalessAttributes::class, ]; + protected $schemalessAttributes = [ + 'proxy', + ]; + protected $fillable = [ + 'name', + 'ip', + 'user', + 'port', + 'team_id', + 'private_key_id', + 'proxy', + ]; + + static public function isReachable() + { + return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true); + } + + static public function ownedByCurrentTeam(array $select = ['*']) + { + $selectArray = collect($select)->concat(['id']); + return Server::whereTeamId(session('currentTeam')->id)->with('settings')->select($selectArray->all())->orderBy('name'); + } + + static public function isUsable() + { + return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true)->whereRelation('settings', 'is_usable', true); + } + + static public function destinationsByServer(string $server_id) + { + $server = Server::ownedByCurrentTeam()->get()->where('id', $server_id)->firstOrFail(); + $standaloneDocker = collect($server->standaloneDockers->all()); + $swarmDocker = collect($server->swarmDockers->all()); + return $standaloneDocker->concat($swarmDocker); + } + protected static function booted() { static::created(function ($server) { @@ -26,22 +61,17 @@ protected static function booted() $server->settings()->delete(); }); } - protected $fillable = [ - 'name', - 'ip', - 'user', - 'port', - 'team_id', - 'private_key_id', - 'proxy', - ]; - + public function settings() + { + return $this->hasOne(ServerSetting::class); + } public function scopeWithProxy(): Builder { return $this->proxy->modelScope(); } + public function isEmpty() { if ($this->applications()->count() === 0) { @@ -49,18 +79,21 @@ public function isEmpty() } return false; } + public function applications() { return $this->destinations()->map(function ($standaloneDocker) { return $standaloneDocker->applications; })->flatten(); } + public function destinations() { $standalone_docker = $this->hasMany(StandaloneDocker::class)->get(); $swarm_docker = $this->hasMany(SwarmDocker::class)->get(); return $standalone_docker->concat($swarm_docker); } + public function standaloneDockers() { return $this->hasMany(StandaloneDocker::class); @@ -76,38 +109,13 @@ public function privateKey() return $this->belongsTo(PrivateKey::class); } - public function settings() - { - return $this->hasOne(ServerSetting::class); - } public function muxFilename() { return "{$this->ip}_{$this->port}_{$this->user}"; } + public function team() { return $this->belongsTo(Team::class); } - static public function ownedByCurrentTeam(array $select = ['*']) - { - $selectArray = collect($select)->concat(['id']); - return Server::whereTeamId(session('currentTeam')->id)->with('settings')->select($selectArray->all())->orderBy('name'); - } - - static public function isReachable() - { - return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true); - } - static public function isUsable() - { - return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true)->whereRelation('settings', 'is_usable', true); - } - - static public function destinationsByServer(string $server_id) - { - $server = Server::ownedByCurrentTeam()->get()->where('id', $server_id)->firstOrFail(); - $standaloneDocker = collect($server->standaloneDockers->all()); - $swarmDocker = collect($server->swarmDockers->all()); - return $standaloneDocker->concat($swarmDocker); - } } diff --git a/app/Models/ServerSetting.php b/app/Models/ServerSetting.php index 6fdf931e7..198600735 100644 --- a/app/Models/ServerSetting.php +++ b/app/Models/ServerSetting.php @@ -10,6 +10,7 @@ class ServerSetting extends Model 'server_id', 'is_usable', ]; + public function server() { return $this->belongsTo(Server::class); diff --git a/app/Models/Service.php b/app/Models/Service.php index e3df5dfa7..fab754360 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -9,6 +9,7 @@ public function environment() { return $this->belongsTo(Environment::class); } + public function destination() { return $this->morphTo(); diff --git a/app/Models/StandaloneDocker.php b/app/Models/StandaloneDocker.php index a21e22e45..9d9f44454 100644 --- a/app/Models/StandaloneDocker.php +++ b/app/Models/StandaloneDocker.php @@ -9,18 +9,22 @@ class StandaloneDocker extends BaseModel 'network', 'server_id', ]; + public function applications() { return $this->morphMany(Application::class, 'destination'); } + public function postgresqls() { return $this->morphMany(StandalonePostgresql::class, 'destination'); } + public function server() { return $this->belongsTo(Server::class); } + public function attachedTo() { return $this->applications->count() > 0 || $this->databases->count() > 0; diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index 1fffb8b83..e48100c59 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -4,12 +4,16 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; -use App\Models\EnvironmentVariable; -use App\Models\LocalPersistentVolume; class StandalonePostgresql extends BaseModel { use HasFactory; + + protected $guarded = []; + protected $casts = [ + 'postgres_password' => 'encrypted', + ]; + protected static function booted() { static::created(function ($database) { @@ -23,29 +27,32 @@ protected static function booted() ]); }); } - protected $guarded = []; - protected $casts = [ - 'postgres_password' => 'encrypted', - ]; - public function type() { + + public function type() + { return 'standalone-postgresql'; } + public function environment() { return $this->belongsTo(Environment::class); } + public function destination() { return $this->morphTo(); } - public function environment_variables(): HasMany + + public function environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class); } + public function runtime_environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class); } + public function persistentStorages() { return $this->morphMany(LocalPersistentVolume::class, 'resource'); diff --git a/app/Models/Subscription.php b/app/Models/Subscription.php index 380660b77..89c4264cb 100644 --- a/app/Models/Subscription.php +++ b/app/Models/Subscription.php @@ -2,12 +2,12 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Subscription extends Model { protected $guarded = []; + public function team() { return $this->belongsTo(Team::class); diff --git a/app/Models/SwarmDocker.php b/app/Models/SwarmDocker.php index b0f341b9b..ea56f85bc 100644 --- a/app/Models/SwarmDocker.php +++ b/app/Models/SwarmDocker.php @@ -8,6 +8,7 @@ public function applications() { return $this->morphMany(Application::class, 'destination'); } + public function server() { return $this->belongsTo(Server::class); diff --git a/app/Models/Team.php b/app/Models/Team.php index 331c969d7..c377ca955 100644 --- a/app/Models/Team.php +++ b/app/Models/Team.php @@ -2,13 +2,10 @@ namespace App\Models; -use App\Notifications\Channels\SendsEmail; use App\Notifications\Channels\SendsDiscord; -use Illuminate\Database\Eloquent\Builder; +use App\Notifications\Channels\SendsEmail; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; -use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; -use Spatie\SchemalessAttributes\SchemalessAttributesTrait; class Team extends Model implements SendsDiscord, SendsEmail { @@ -23,9 +20,10 @@ public function routeNotificationForDiscord() { return data_get($this, 'discord_webhook_url', null); } + public function getRecepients($notification) { - $recipients = data_get($notification,'emails',null); + $recipients = data_get($notification, 'emails', null); if (is_null($recipients)) { $recipients = $this->members()->pluck('email')->toArray(); return $recipients; @@ -33,10 +31,34 @@ public function getRecepients($notification) return explode(',', $recipients); } + public function members() + { + return $this->belongsToMany(User::class, 'team_user', 'team_id', 'user_id')->withPivot('role'); + } + public function subscription() { return $this->hasOne(Subscription::class); } + + public function applications() + { + return $this->hasManyThrough(Application::class, Project::class); + } + + public function invitations() + { + return $this->hasMany(TeamInvitation::class); + } + + public function isEmpty() + { + if ($this->projects()->count() === 0 && $this->servers()->count() === 0 && $this->privateKeys()->count() === 0 && $this->sources()->count() === 0) { + return true; + } + return false; + } + public function projects() { return $this->hasMany(Project::class); @@ -47,23 +69,11 @@ public function servers() return $this->hasMany(Server::class); } - public function applications() - { - return $this->hasManyThrough(Application::class, Project::class); - } - public function privateKeys() { return $this->hasMany(PrivateKey::class); } - public function members() - { - return $this->belongsToMany(User::class, 'team_user', 'team_id', 'user_id')->withPivot('role'); - } - public function invitations() - { - return $this->hasMany(TeamInvitation::class); - } + public function sources() { $sources = collect([]); @@ -73,11 +83,4 @@ public function sources() $sources = $sources->merge($github_apps)->merge($gitlab_apps); return $sources; } - public function isEmpty() - { - if ($this->projects()->count() === 0 && $this->servers()->count() === 0 && $this->privateKeys()->count() === 0 && $this->sources()->count() === 0) { - return true; - } - return false; - } -} \ No newline at end of file +} diff --git a/app/Models/TeamInvitation.php b/app/Models/TeamInvitation.php index c326d7d40..a5c382b3b 100644 --- a/app/Models/TeamInvitation.php +++ b/app/Models/TeamInvitation.php @@ -14,6 +14,7 @@ class TeamInvitation extends Model 'link', 'via', ]; + public function team() { return $this->belongsTo(Team::class); diff --git a/app/Models/User.php b/app/Models/User.php index d9f1eaa6a..47ed5a995 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -3,18 +3,17 @@ namespace App\Models; use App\Notifications\Channels\SendsEmail; +use App\Notifications\TrnsactionalEmails\ResetPassword; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; -use Laravel\Sanctum\HasApiTokens; -use Visus\Cuid2\Cuid2; use Laravel\Fortify\TwoFactorAuthenticatable; -use App\Notifications\TrnsactionalEmails\ResetPassword; +use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable implements SendsEmail { use HasApiTokens, HasFactory, Notifiable, TwoFactorAuthenticatable; + protected $fillable = [ 'id', 'name', @@ -28,6 +27,7 @@ class User extends Authenticatable implements SendsEmail protected $casts = [ 'email_verified_at' => 'datetime', ]; + protected static function boot() { parent::boot(); @@ -44,18 +44,27 @@ protected static function boot() $user->teams()->attach($new_team, ['role' => 'owner']); }); } + + public function teams() + { + return $this->belongsToMany(Team::class)->withPivot('role'); + } + public function getRecepients($notification) { return $this->email; } + public function sendPasswordResetNotification($token): void { $this->notify(new ResetPassword($token)); } + public function isAdmin() { return $this->pivot->role === 'admin' || $this->pivot->role === 'owner'; } + public function isAdminFromSession() { if (auth()->user()->id === 0) { @@ -73,6 +82,7 @@ public function isAdminFromSession() $role = $teams->where('id', session('currentTeam')->id)->first()->pivot->role; return $role === 'admin' || $role === 'owner'; } + public function isInstanceAdmin() { $found_root_team = auth()->user()->teams->filter(function ($team) { @@ -83,18 +93,17 @@ public function isInstanceAdmin() }); return $found_root_team->count() > 0; } + public function personalTeam() { return $this->teams()->where('personal_team', true)->first(); } - public function teams() - { - return $this->belongsToMany(Team::class)->withPivot('role'); - } + public function currentTeam() { return $this->teams()->where('team_id', session('currentTeam')->id)->first(); } + public function otherTeams() { $team_id = session('currentTeam')->id; @@ -102,6 +111,7 @@ public function otherTeams() return $team->id != $team_id; }); } + public function role() { if ($this->teams()->where('team_id', 0)->first()) { @@ -109,10 +119,11 @@ public function role() } return $this->teams()->where('team_id', session('currentTeam')->id)->first()->pivot->role; } + public function resources() { $team_id = session('currentTeam')->id; $data = Application::where('team_id', $team_id)->get(); return $data; } -} \ No newline at end of file +} diff --git a/app/Models/Webhook.php b/app/Models/Webhook.php index 079b926be..308f17370 100644 --- a/app/Models/Webhook.php +++ b/app/Models/Webhook.php @@ -2,7 +2,6 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Webhook extends Model @@ -11,4 +10,4 @@ class Webhook extends Model protected $casts = [ 'payload' => 'encrypted', ]; -} \ No newline at end of file +} diff --git a/app/Notifications/Application/DeploymentFailed.php b/app/Notifications/Application/DeploymentFailed.php index 053f432eb..bc7f5dfde 100644 --- a/app/Notifications/Application/DeploymentFailed.php +++ b/app/Notifications/Application/DeploymentFailed.php @@ -4,9 +4,8 @@ use App\Models\Application; use App\Models\ApplicationPreview; -use App\Models\Team; -use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\EmailChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -16,6 +15,7 @@ class DeploymentFailed extends Notification implements ShouldQueue { use Queueable; + public Application $application; public string $deployment_uuid; public ApplicationPreview|null $preview; @@ -38,8 +38,9 @@ public function __construct(Application $application, string $deployment_uuid, A if (Str::of($this->fqdn)->explode(',')->count() > 1) { $this->fqdn = Str::of($this->fqdn)->explode(',')->first(); } - $this->deployment_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; + $this->deployment_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; } + public function via(object $notifiable): array { $channels = []; @@ -56,6 +57,7 @@ public function via(object $notifiable): array } return $channels; } + public function toMail(): MailMessage { $mail = new MailMessage(); @@ -88,4 +90,4 @@ public function toDiscord(): string } return $message; } -} \ No newline at end of file +} diff --git a/app/Notifications/Application/DeploymentSuccess.php b/app/Notifications/Application/DeploymentSuccess.php index 1821a1bde..99bd2532c 100644 --- a/app/Notifications/Application/DeploymentSuccess.php +++ b/app/Notifications/Application/DeploymentSuccess.php @@ -4,9 +4,8 @@ use App\Models\Application; use App\Models\ApplicationPreview; -use App\Models\Team; -use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\EmailChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -16,6 +15,7 @@ class DeploymentSuccess extends Notification implements ShouldQueue { use Queueable; + public Application $application; public string $deployment_uuid; public ApplicationPreview|null $preview = null; @@ -38,8 +38,9 @@ public function __construct(Application $application, string $deployment_uuid, A if (Str::of($this->fqdn)->explode(',')->count() > 1) { $this->fqdn = Str::of($this->fqdn)->explode(',')->first(); } - $this->deployment_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; + $this->deployment_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; } + public function via(object $notifiable): array { $channels = []; @@ -56,6 +57,7 @@ public function via(object $notifiable): array } return $channels; } + public function toMail(): MailMessage { $mail = new MailMessage(); @@ -97,4 +99,4 @@ public function toDiscord(): string } return $message; } -} \ No newline at end of file +} diff --git a/app/Notifications/Application/StatusChanged.php b/app/Notifications/Application/StatusChanged.php index 4fb279d44..9c6b99fc7 100644 --- a/app/Notifications/Application/StatusChanged.php +++ b/app/Notifications/Application/StatusChanged.php @@ -2,10 +2,8 @@ namespace App\Notifications\Application; -use App\Models\Application; -use App\Models\ApplicationPreview; -use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\EmailChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -15,6 +13,7 @@ class StatusChanged extends Notification implements ShouldQueue { use Queueable; + public $application; public string $application_name; @@ -33,8 +32,9 @@ public function __construct($application) if (Str::of($this->fqdn)->explode(',')->count() > 1) { $this->fqdn = Str::of($this->fqdn)->explode(',')->first(); } - $this->application_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}"; + $this->application_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}"; } + public function via(object $notifiable): array { $channels = []; @@ -51,6 +51,7 @@ public function via(object $notifiable): array } return $channels; } + public function toMail(): MailMessage { $mail = new MailMessage(); @@ -72,4 +73,4 @@ public function toDiscord(): string $message .= '[Application URL](' . $this->application_url . ')'; return $message; } -} \ No newline at end of file +} diff --git a/app/Notifications/Channels/EmailChannel.php b/app/Notifications/Channels/EmailChannel.php index 22b5e59a0..044bb9b07 100644 --- a/app/Notifications/Channels/EmailChannel.php +++ b/app/Notifications/Channels/EmailChannel.php @@ -22,7 +22,7 @@ public function send(SendsEmail $notifiable, Notification $notification): void Mail::send( [], [], - fn (Message $message) => $message + fn(Message $message) => $message ->from( data_get($notifiable, 'smtp_from_address'), data_get($notifiable, 'smtp_from_name'), @@ -50,4 +50,4 @@ private function bootConfigs($notifiable): void "local_domain" => null, ]); } -} \ No newline at end of file +} diff --git a/app/Notifications/Channels/TransactionalEmailChannel.php b/app/Notifications/Channels/TransactionalEmailChannel.php index 848bb1bc8..3d5328f81 100644 --- a/app/Notifications/Channels/TransactionalEmailChannel.php +++ b/app/Notifications/Channels/TransactionalEmailChannel.php @@ -25,7 +25,7 @@ public function send(User $notifiable, Notification $notification): void Mail::send( [], [], - fn (Message $message) => $message + fn(Message $message) => $message ->from( data_get($settings, 'smtp_from_address'), data_get($settings, 'smtp_from_name') @@ -40,4 +40,4 @@ private function bootConfigs(): void { set_transanctional_email_settings(); } -} \ No newline at end of file +} diff --git a/app/Notifications/Test.php b/app/Notifications/Test.php index c7fc9f714..4cec28cfd 100644 --- a/app/Notifications/Test.php +++ b/app/Notifications/Test.php @@ -2,8 +2,8 @@ namespace App\Notifications; -use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\EmailChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -12,8 +12,10 @@ class Test extends Notification implements ShouldQueue { use Queueable; + public function __construct(public string|null $emails = null) - {} + { + } public function via(object $notifiable): array { @@ -30,6 +32,7 @@ public function via(object $notifiable): array } return $channels; } + public function toMail(): MailMessage { $mail = new MailMessage(); @@ -37,6 +40,7 @@ public function toMail(): MailMessage $mail->view('emails.test'); return $mail; } + public function toDiscord(): string { $message = 'This is a test Discord notification from Coolify.'; @@ -44,4 +48,4 @@ public function toDiscord(): string $message .= '[Go to your dashboard](' . base_url() . ')'; return $message; } -} \ No newline at end of file +} diff --git a/app/Notifications/TransactionalEmails/InvitationLink.php b/app/Notifications/TransactionalEmails/InvitationLink.php index 7785f92cc..f08c36fbc 100644 --- a/app/Notifications/TransactionalEmails/InvitationLink.php +++ b/app/Notifications/TransactionalEmails/InvitationLink.php @@ -14,6 +14,7 @@ class InvitationLink extends Notification implements ShouldQueue { use Queueable; + public function via() { return [TransactionalEmailChannel::class]; @@ -33,4 +34,4 @@ public function toMail(User $user): MailMessage ]); return $mail; } -} \ No newline at end of file +} diff --git a/app/Notifications/TransactionalEmails/ResetPassword.php b/app/Notifications/TransactionalEmails/ResetPassword.php index 856d5b697..816c1a671 100644 --- a/app/Notifications/TransactionalEmails/ResetPassword.php +++ b/app/Notifications/TransactionalEmails/ResetPassword.php @@ -2,26 +2,36 @@ namespace App\Notifications\TransactionalEmails; +use App\Models\InstanceSettings; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; -use Illuminate\Support\Facades\Lang; -use App\Models\InstanceSettings; class ResetPassword extends Notification { - public $token; - public InstanceSettings $settings; public static $createUrlCallback; public static $toMailCallback; + public $token; + public InstanceSettings $settings; public function __construct($token) { $this->settings = InstanceSettings::get(); $this->token = $token; } + + public static function createUrlUsing($callback) + { + static::$createUrlCallback = $callback; + } + + public static function toMailUsing($callback) + { + static::$toMailCallback = $callback; + } + public function via($notifiable) { - if ($this->settings->smtp_enabled){ + if ($this->settings->smtp_enabled) { $password = data_get($this->settings, 'smtp_password'); if ($password) $password = decrypt($password); @@ -50,6 +60,7 @@ public function toMail($notifiable) return $this->buildMailMessage($this->resetUrl($notifiable)); } + protected function buildMailMessage($url) { $mail = new MailMessage(); @@ -58,9 +69,10 @@ protected function buildMailMessage($url) data_get($this->settings, 'smtp_from_name'), ); $mail->subject('Reset Password'); - $mail->view('emails.reset-password', ['url' => $url,'count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]); + $mail->view('emails.reset-password', ['url' => $url, 'count' => config('auth.passwords.' . config('auth.defaults.passwords') . '.expire')]); return $mail; } + protected function resetUrl($notifiable) { if (static::$createUrlCallback) { @@ -72,12 +84,4 @@ protected function resetUrl($notifiable) 'email' => $notifiable->getEmailForPasswordReset(), ], false)); } - public static function createUrlUsing($callback) - { - static::$createUrlCallback = $callback; - } - public static function toMailUsing($callback) - { - static::$toMailCallback = $callback; - } -} \ No newline at end of file +} diff --git a/app/Notifications/TransactionalEmails/Test.php b/app/Notifications/TransactionalEmails/Test.php index a07130ad2..f5962fc2a 100644 --- a/app/Notifications/TransactionalEmails/Test.php +++ b/app/Notifications/TransactionalEmails/Test.php @@ -13,7 +13,8 @@ class Test extends Notification implements ShouldQueue use Queueable; public function __construct(public string $emails) - {} + { + } public function via(): array { @@ -27,4 +28,4 @@ public function toMail(): MailMessage $mail->view('emails.test'); return $mail; } -} \ No newline at end of file +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index b8c70b770..07d02cd03 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,7 +2,6 @@ namespace App\Providers; -use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Http; use Illuminate\Support\ServiceProvider; diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 2d65aac0e..87c58d172 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -5,7 +5,6 @@ use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; -use Illuminate\Support\Facades\Event; class EventServiceProvider extends ServiceProvider { diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php index 0a3d02ff7..b3e67c255 100644 --- a/app/Providers/FortifyServiceProvider.php +++ b/app/Providers/FortifyServiceProvider.php @@ -23,8 +23,7 @@ class FortifyServiceProvider extends ServiceProvider */ public function register(): void { - $this->app->instance(RegisterResponse::class, new class implements RegisterResponse - { + $this->app->instance(RegisterResponse::class, new class implements RegisterResponse { public function toResponse($request) { // First user (root) will be redirected to /settings instead of / on registration. @@ -92,7 +91,7 @@ public function boot(): void }); RateLimiter::for('login', function (Request $request) { - $email = (string) $request->email; + $email = (string)$request->email; return Limit::perMinute(5)->by($email . $request->ip()); }); diff --git a/app/Traits/ExecuteRemoteCommand.php b/app/Traits/ExecuteRemoteCommand.php index 6e8c5b761..24e17a73d 100644 --- a/app/Traits/ExecuteRemoteCommand.php +++ b/app/Traits/ExecuteRemoteCommand.php @@ -3,7 +3,6 @@ namespace App\Traits; use App\Enums\ApplicationDeploymentStatus; -use App\Models\ApplicationDeploymentQueue; use App\Models\Server; use Carbon\Carbon; use Illuminate\Support\Collection; @@ -13,6 +12,7 @@ trait ExecuteRemoteCommand { public string|null $save = null; + public function execute_remote_command(...$commands) { static::$batch_counter++; diff --git a/app/View/Components/Forms/Button.php b/app/View/Components/Forms/Button.php index faa2632b7..e4df04cf6 100644 --- a/app/View/Components/Forms/Button.php +++ b/app/View/Components/Forms/Button.php @@ -12,12 +12,13 @@ class Button extends Component * Create a new component instance. */ public function __construct( - public bool $disabled = false, - public bool $isModal = false, - public bool $noStyle = false, + public bool $disabled = false, + public bool $isModal = false, + public bool $noStyle = false, public string|null $modalId = null, - public string $defaultClass = "btn btn-primary btn-sm font-normal text-white normal-case no-animation rounded border-none" - ) { + public string $defaultClass = "btn btn-primary btn-sm font-normal text-white normal-case no-animation rounded border-none" + ) + { if ($this->noStyle) { $this->defaultClass = ""; } @@ -30,4 +31,4 @@ public function render(): View|Closure|string { return view('components.forms.button'); } -} \ No newline at end of file +} diff --git a/app/View/Components/Forms/Checkbox.php b/app/View/Components/Forms/Checkbox.php index b79066775..e730266a3 100644 --- a/app/View/Components/Forms/Checkbox.php +++ b/app/View/Components/Forms/Checkbox.php @@ -17,10 +17,11 @@ public function __construct( public string|null $value = null, public string|null $label = null, public string|null $helper = null, - public bool $instantSave = false, - public bool $disabled = false, - public string $defaultClass = "toggle toggle-xs toggle-warning rounded disabled:bg-coolgray-200 disabled:opacity-50 placeholder:text-neutral-700" - ) { + public bool $instantSave = false, + public bool $disabled = false, + public string $defaultClass = "toggle toggle-xs toggle-warning rounded disabled:bg-coolgray-200 disabled:opacity-50 placeholder:text-neutral-700" + ) + { // } diff --git a/app/View/Components/Forms/Input.php b/app/View/Components/Forms/Input.php index 1e517ea3f..c74bfa2ec 100644 --- a/app/View/Components/Forms/Input.php +++ b/app/View/Components/Forms/Input.php @@ -6,7 +6,6 @@ use Illuminate\Contracts\View\View; use Illuminate\View\Component; use Visus\Cuid2\Cuid2; -use Illuminate\Support\Str; class Input extends Component { @@ -16,13 +15,14 @@ public function __construct( public string|null $type = 'text', public string|null $value = null, public string|null $label = null, - public bool $required = false, - public bool $disabled = false, - public bool $readonly = false, + public bool $required = false, + public bool $disabled = false, + public bool $readonly = false, public string|null $helper = null, - public bool $allowToPeak = true, - public string $defaultClass = "input input-sm bg-coolgray-200 rounded text-white w-full disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500" - ) { + public bool $allowToPeak = true, + public string $defaultClass = "input input-sm bg-coolgray-200 rounded text-white w-full disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500" + ) + { } public function render(): View|Closure|string @@ -33,4 +33,4 @@ public function render(): View|Closure|string // $this->label = Str::title($this->label); return view('components.forms.input'); } -} \ No newline at end of file +} diff --git a/app/View/Components/Forms/Select.php b/app/View/Components/Forms/Select.php index 8dfd43582..f74cd3109 100644 --- a/app/View/Components/Forms/Select.php +++ b/app/View/Components/Forms/Select.php @@ -4,9 +4,9 @@ use Closure; use Illuminate\Contracts\View\View; +use Illuminate\Support\Str; use Illuminate\View\Component; use Visus\Cuid2\Cuid2; -use Illuminate\Support\Str; class Select extends Component { @@ -18,9 +18,10 @@ public function __construct( public string|null $name = null, public string|null $label = null, public string|null $helper = null, - public bool $required = false, - public string $defaultClass = "select select-sm w-full rounded text-white text-sm bg-coolgray-200 font-normal disabled:bg-coolgray-200/50 disabled:border-none" - ) { + public bool $required = false, + public string $defaultClass = "select select-sm w-full rounded text-white text-sm bg-coolgray-200 font-normal disabled:bg-coolgray-200/50 disabled:border-none" + ) + { // } diff --git a/app/View/Components/Forms/Textarea.php b/app/View/Components/Forms/Textarea.php index f4d1f0bee..5a017c56b 100644 --- a/app/View/Components/Forms/Textarea.php +++ b/app/View/Components/Forms/Textarea.php @@ -4,9 +4,9 @@ use Closure; use Illuminate\Contracts\View\View; +use Illuminate\Support\Str; use Illuminate\View\Component; use Visus\Cuid2\Cuid2; -use Illuminate\Support\Str; class Textarea extends Component { @@ -20,12 +20,13 @@ public function __construct( public string|null $value = null, public string|null $label = null, public string|null $placeholder = null, - public bool $required = false, - public bool $disabled = false, - public bool $readonly = false, + public bool $required = false, + public bool $disabled = false, + public bool $readonly = false, public string|null $helper = null, - public string $defaultClass = "textarea bg-coolgray-200 rounded text-white scrollbar disabled:bg-coolgray-200/50 disabled:border-none" - ) { + public string $defaultClass = "textarea bg-coolgray-200 rounded text-white scrollbar disabled:bg-coolgray-200/50 disabled:border-none" + ) + { // } diff --git a/app/View/Components/Modal.php b/app/View/Components/Modal.php index 22c5a7bba..0b7d66dae 100644 --- a/app/View/Components/Modal.php +++ b/app/View/Components/Modal.php @@ -5,7 +5,6 @@ use Closure; use Illuminate\Contracts\View\View; use Illuminate\View\Component; -use Visus\Cuid2\Cuid2; class Modal extends Component { @@ -13,13 +12,14 @@ class Modal extends Component * Create a new component instance. */ public function __construct( - public string $modalId, + public string $modalId, public string|null $modalTitle = null, public string|null $modalBody = null, public string|null $modalSubmit = null, - public bool $yesOrNo = false, - public string $action = 'delete' - ) { + public bool $yesOrNo = false, + public string $action = 'delete' + ) + { // } @@ -30,4 +30,4 @@ public function render(): View|Closure|string { return view('components.modal'); } -} \ No newline at end of file +} diff --git a/bootstrap/app.php b/bootstrap/app.php index 55afdbffb..037e17df0 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -11,8 +11,6 @@ | */ -use Illuminate\Support\Facades\Artisan; - $app = new Illuminate\Foundation\Application( $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__) ); diff --git a/bootstrap/helpers/applications.php b/bootstrap/helpers/applications.php index fa57cebde..f1b4d9104 100644 --- a/bootstrap/helpers/applications.php +++ b/bootstrap/helpers/applications.php @@ -16,7 +16,7 @@ function queue_application_deployment(int $application_id, string $deployment_uu ]); $queued_deployments = ApplicationDeploymentQueue::where('application_id', $application_id)->where('status', 'queued')->get()->sortByDesc('created_at'); $running_deployments = ApplicationDeploymentQueue::where('application_id', $application_id)->where('status', 'in_progress')->get()->sortByDesc('created_at'); - ray('Q:' . $queued_deployments->count() . 'R:' . $running_deployments->count() . '| Queuing deployment: ' . $deployment_uuid . ' of applicationID: ' . $application_id . ' pull request: ' . $pull_request_id . ' with commit: ' . $commit . ' and is it forced: ' . $force_rebuild); + ray('Q:' . $queued_deployments->count() . 'R:' . $running_deployments->count() . '| Queuing deployment: ' . $deployment_uuid . ' of applicationID: ' . $application_id . ' pull request: ' . $pull_request_id . ' with commit: ' . $commit . ' and is it forced: ' . $force_rebuild); if ($queued_deployments->count() > 1) { $queued_deployments = $queued_deployments->skip(1); $queued_deployments->each(function ($queued_deployment, $key) { diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index a8bd2a2f7..18882647b 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -8,15 +8,16 @@ function format_docker_command_output_to_json($rawOutput): Collection $outputLines = explode(PHP_EOL, $rawOutput); return collect($outputLines) - ->reject(fn ($line) => empty($line)) - ->map(fn ($outputLine) => json_decode($outputLine, true, flags: JSON_THROW_ON_ERROR)); + ->reject(fn($line) => empty($line)) + ->map(fn($outputLine) => json_decode($outputLine, true, flags: JSON_THROW_ON_ERROR)); } + function format_docker_labels_to_json($rawOutput): Collection { $outputLines = explode(PHP_EOL, $rawOutput); return collect($outputLines) - ->reject(fn ($line) => empty($line)) + ->reject(fn($line) => empty($line)) ->map(function ($outputLine) { $outputArray = explode(',', $outputLine); return collect($outputArray) diff --git a/bootstrap/helpers/github.php b/bootstrap/helpers/github.php index 8d18e6290..5c36f091d 100644 --- a/bootstrap/helpers/github.php +++ b/bootstrap/helpers/github.php @@ -3,8 +3,8 @@ use App\Models\GithubApp; use App\Models\GitlabApp; use Carbon\Carbon; -use Illuminate\Support\Str; use Illuminate\Support\Facades\Http; +use Illuminate\Support\Str; use Lcobucci\JWT\Encoding\ChainedFormatter; use Lcobucci\JWT\Encoding\JoseEncoder; use Lcobucci\JWT\Signer\Key\InMemory; @@ -33,6 +33,7 @@ function generate_github_installation_token(GithubApp $source) } return $token->json()['token']; } + function generate_github_jwt_token(GithubApp $source) { $signingKey = InMemory::plainText($source->privateKey->private_key); @@ -65,7 +66,7 @@ function git_api(GithubApp|GitlabApp $source, string $endpoint, string $method = } $json = $response->json(); if ($response->failed() && $throwError) { - throw new \Exception("Failed to get data from {$source->name} with error:

" . $json['message'] . "

Rate Limit resets at: " . Carbon::parse((int)$response->header('X-RateLimit-Reset'))->format('Y-m-d H:i:s') . 'UTC'); + throw new \Exception("Failed to get data from {$source->name} with error:

" . $json['message'] . "

Rate Limit resets at: " . Carbon::parse((int)$response->header('X-RateLimit-Reset'))->format('Y-m-d H:i:s') . 'UTC'); } return [ 'rate_limit_remaining' => $response->header('X-RateLimit-Remaining'), @@ -73,6 +74,7 @@ function git_api(GithubApp|GitlabApp $source, string $endpoint, string $method = 'data' => collect($json) ]; } + function get_installation_path(GithubApp $source) { $github = GithubApp::where('uuid', $source->uuid)->first(); diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index 9d2cc7e45..1ae747686 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -1,15 +1,15 @@ - [ - 'routers' => [ - 'catchall' => - [ - 'entryPoints' => [ - 0 => 'http', - 1 => 'https', - ], - 'service' => 'noop', - 'rule' => "HostRegexp(`{catchall:.*}`)", - 'priority' => 1, - 'middlewares' => [ - 0 => 'redirect-regexp@file', - ], - ], - ], - 'services' => - [ - 'noop' => - [ - 'loadBalancer' => + 'routers' => [ - 'servers' => - [ - 0 => + 'catchall' => [ - 'url' => '', + 'entryPoints' => [ + 0 => 'http', + 1 => 'https', + ], + 'service' => 'noop', + 'rule' => "HostRegexp(`{catchall:.*}`)", + 'priority' => 1, + 'middlewares' => [ + 0 => 'redirect-regexp@file', + ], ], - ], ], - ], - ], - 'middlewares' => - [ - 'redirect-regexp' => - [ - 'redirectRegex' => + 'services' => [ - 'regex' => '(.*)', - 'replacement' => $redirect_url, - 'permanent' => false, + 'noop' => + [ + 'loadBalancer' => + [ + 'servers' => + [ + 0 => + [ + 'url' => '', + ], + ], + ], + ], + ], + 'middlewares' => + [ + 'redirect-regexp' => + [ + 'redirectRegex' => + [ + 'regex' => '(.*)', + 'replacement' => $redirect_url, + 'permanent' => false, + ], + ], ], - ], ], - ], ]; $yaml = Yaml::dump($traefik_dynamic_conf, 12, 2); $yaml = @@ -167,4 +168,4 @@ function setup_default_redirect_404(string|null $redirect_url, Server $server) ray($yaml); } } -} \ No newline at end of file +} diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index 93d48d77a..422b9c2ee 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -23,11 +23,12 @@ function remote_process( array $command, Server $server, - string $type = ActivityTypes::INLINE->value, + string $type = ActivityTypes::INLINE->value, ?string $type_uuid = null, ?Model $model = null, bool $ignore_errors = false, -): Activity { +): Activity +{ $command_string = implode("\n", $command); if (auth()->user()) { @@ -55,11 +56,13 @@ function remote_process( ), ])(); } + function get_private_key_for_server(Server $server) { $temp_file = "id.root@{$server->ip}"; return '/var/www/html/storage/app/ssh/keys/' . $temp_file; } + function save_private_key_for_server(Server $server) { if (data_get($server, 'privateKey.private_key') === null) { @@ -138,10 +141,10 @@ function decode_remote_command_output(?ApplicationDeploymentQueue $application_d } $formatted = collect($decoded); if (!$is_debug_enabled) { - $formatted = $formatted->filter(fn ($i) => $i['hidden'] === false ?? false); + $formatted = $formatted->filter(fn($i) => $i['hidden'] === false ?? false); } $formatted = $formatted - ->sortBy(fn ($i) => $i['order']) + ->sortBy(fn($i) => $i['order']) ->map(function ($i) { $i['timestamp'] = Carbon::parse($i['timestamp'])->format('Y-M-d H:i:s.u'); return $i; diff --git a/bootstrap/helpers/s3.php b/bootstrap/helpers/s3.php index 12f53cd02..4a2252016 100644 --- a/bootstrap/helpers/s3.php +++ b/bootstrap/helpers/s3.php @@ -3,20 +3,21 @@ use App\Models\S3Storage; use Illuminate\Support\Str; -function set_s3_target(S3Storage $s3) { +function set_s3_target(S3Storage $s3) +{ $is_digital_ocean = false; if ($s3->endpoint) { - $is_digital_ocean = Str::contains($s3->endpoint,'digitaloceanspaces.com'); + $is_digital_ocean = Str::contains($s3->endpoint, 'digitaloceanspaces.com'); } config()->set('filesystems.disks.custom-s3', [ - 'driver' => 's3', - 'region' => $s3['region'], - 'key' => $s3['key'], - 'secret' => $s3['secret'], - 'bucket' => $s3['bucket'], - 'endpoint' => $s3['endpoint'], - 'use_path_style_endpoint' => true, - 'bucket_endpoint' => $is_digital_ocean, - 'aws_url' => $s3->awsUrl(), + 'driver' => 's3', + 'region' => $s3['region'], + 'key' => $s3['key'], + 'secret' => $s3['secret'], + 'bucket' => $s3['bucket'], + 'endpoint' => $s3['endpoint'], + 'use_path_style_endpoint' => true, + 'bucket_endpoint' => $is_digital_ocean, + 'aws_url' => $s3->awsUrl(), ]); -} \ No newline at end of file +} diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 69cfe6f4b..2954c37eb 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -4,9 +4,8 @@ use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Route; -use Illuminate\Support\Facades\URL; -use Visus\Cuid2\Cuid2; use Illuminate\Support\Str; +use Visus\Cuid2\Cuid2; function general_error_handler(\Throwable|null $err = null, $that = null, $isJson = false, $customErrorMessage = null) { @@ -62,6 +61,7 @@ function generate_random_name() $cuid = new Cuid2(7); return Str::kebab("{$generator->getName()}-{$cuid}"); } + function generate_application_name(string $git_repository, string $git_branch) { $cuid = new Cuid2(7); @@ -91,6 +91,7 @@ function set_transanctional_email_settings() "local_domain" => null, ]); } + function base_ip() { if (isDev()) { @@ -99,6 +100,7 @@ function base_ip() $settings = InstanceSettings::get(); return "http://{$settings->public_ipv4}"; } + function base_url(bool $withPort = true) { $settings = InstanceSettings::get(); @@ -131,7 +133,8 @@ function isDev() { return config('app.env') === 'local'; } + function isCloud() { return !config('coolify.self_hosted'); -} \ No newline at end of file +} diff --git a/bootstrap/helpers/subscriptions.php b/bootstrap/helpers/subscriptions.php index 1a5fc5ffe..8383bc51b 100644 --- a/bootstrap/helpers/subscriptions.php +++ b/bootstrap/helpers/subscriptions.php @@ -27,18 +27,22 @@ function getSubscriptionLink($id) } return $url; } + function getPaymentLink() { return auth()->user()->currentTeam()->subscription->lemon_update_payment_menthod_url; } + function getRenewDate() { return Carbon::parse(auth()->user()->currentTeam()->subscription->lemon_renews_at)->format('Y-M-d H:i:s'); } + function getEndDate() { return Carbon::parse(auth()->user()->currentTeam()->subscription->lemon_renews_at)->format('Y-M-d H:i:s'); } + function isSubscribed() { return diff --git a/config/app.php b/config/app.php index 78df1ec8a..690029fd6 100644 --- a/config/app.php +++ b/config/app.php @@ -43,7 +43,7 @@ | */ - 'debug' => (bool) env('APP_DEBUG', false), + 'debug' => (bool)env('APP_DEBUG', false), /* |-------------------------------------------------------------------------- diff --git a/config/broadcasting.php b/config/broadcasting.php index 9e4d4aa44..4dbd22c7e 100644 --- a/config/broadcasting.php +++ b/config/broadcasting.php @@ -36,7 +36,7 @@ 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ - 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', + 'host' => env('PUSHER_HOST') ?: 'api-' . env('PUSHER_APP_CLUSTER', 'mt1') . '.pusher.com', 'port' => env('PUSHER_PORT', 443), 'scheme' => env('PUSHER_SCHEME', 'https'), 'encrypted' => true, diff --git a/config/logging.php b/config/logging.php index 4c3df4ce1..a97262cb3 100644 --- a/config/logging.php +++ b/config/logging.php @@ -85,7 +85,7 @@ 'handler_with' => [ 'host' => env('PAPERTRAIL_URL'), 'port' => env('PAPERTRAIL_PORT'), - 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://' . env('PAPERTRAIL_URL') . ':' . env('PAPERTRAIL_PORT'), ], ], diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 31ddf8720..d874cd9dc 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -30,7 +30,7 @@ public function definition(): array */ public function unverified(): static { - return $this->state(fn (array $attributes) => [ + return $this->state(fn(array $attributes) => [ 'email_verified_at' => null, ]); } diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 321128a8f..2b909d2e2 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php b/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php index 81a7229b0..1bc0eeeae 100644 --- a/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php +++ b/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php index 5cc9f78b1..eb46a82cc 100644 --- a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php +++ b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php @@ -5,8 +5,7 @@ use Illuminate\Support\Facades\Schema; use Laravel\Fortify\Fortify; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -14,17 +13,17 @@ public function up(): void { Schema::table('users', function (Blueprint $table) { $table->text('two_factor_secret') - ->after('password') - ->nullable(); + ->after('password') + ->nullable(); $table->text('two_factor_recovery_codes') - ->after('two_factor_secret') - ->nullable(); + ->after('two_factor_secret') + ->nullable(); if (Fortify::confirmsTwoFactorAuthentication()) { $table->timestamp('two_factor_confirmed_at') - ->after('two_factor_recovery_codes') - ->nullable(); + ->after('two_factor_recovery_codes') + ->nullable(); } }); } diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php index 954f7518f..5f7e6b53d 100644 --- a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_03_20_112410_create_activity_log_table.php b/database/migrations/2023_03_20_112410_create_activity_log_table.php index a6fa05393..c94274b31 100755 --- a/database/migrations/2023_03_20_112410_create_activity_log_table.php +++ b/database/migrations/2023_03_20_112410_create_activity_log_table.php @@ -1,8 +1,8 @@ string('wildcard_domain')->nullable(); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_06_23_110548_next_channel_updates.php b/database/migrations/2023_06_23_110548_next_channel_updates.php index 83c4dacf3..1c2f705b9 100644 --- a/database/migrations/2023_06_23_110548_next_channel_updates.php +++ b/database/migrations/2023_06_23_110548_next_channel_updates.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_06_23_114131_change_env_var_value_length.php b/database/migrations/2023_06_23_114131_change_env_var_value_length.php index ca8bd1e0c..2b0a6e159 100644 --- a/database/migrations/2023_06_23_114131_change_env_var_value_length.php +++ b/database/migrations/2023_06_23_114131_change_env_var_value_length.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_06_23_114132_remove_default_redirect_from_instance_settings.php b/database/migrations/2023_06_23_114132_remove_default_redirect_from_instance_settings.php index 9c14b7c39..66d02e642 100644 --- a/database/migrations/2023_06_23_114132_remove_default_redirect_from_instance_settings.php +++ b/database/migrations/2023_06_23_114132_remove_default_redirect_from_instance_settings.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_06_23_114133_use_application_deployment_queues_as_activity.php b/database/migrations/2023_06_23_114133_use_application_deployment_queues_as_activity.php index 642184abc..440eca662 100644 --- a/database/migrations/2023_06_23_114133_use_application_deployment_queues_as_activity.php +++ b/database/migrations/2023_06_23_114133_use_application_deployment_queues_as_activity.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -27,4 +26,4 @@ public function down(): void $table->dropColumn('current_process_id'); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_06_23_114134_add_disk_usage_percentage_to_servers.php b/database/migrations/2023_06_23_114134_add_disk_usage_percentage_to_servers.php index d2b0f892c..09e9a6093 100644 --- a/database/migrations/2023_06_23_114134_add_disk_usage_percentage_to_servers.php +++ b/database/migrations/2023_06_23_114134_add_disk_usage_percentage_to_servers.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -25,4 +24,4 @@ public function down(): void $table->dropColumn('cleanup_after_percentage'); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_07_13_115117_create_subscriptions_table.php b/database/migrations/2023_07_13_115117_create_subscriptions_table.php index 08aeaaa17..5745c29e2 100644 --- a/database/migrations/2023_07_13_115117_create_subscriptions_table.php +++ b/database/migrations/2023_07_13_115117_create_subscriptions_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -36,4 +35,4 @@ public function down(): void { Schema::dropIfExists('subscriptions'); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_07_13_120719_create_webhooks_table.php b/database/migrations/2023_07_13_120719_create_webhooks_table.php index 9376a10c9..f53d280c1 100644 --- a/database/migrations/2023_07_13_120719_create_webhooks_table.php +++ b/database/migrations/2023_07_13_120719_create_webhooks_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_07_13_120721_add_license_to_instance_settings.php b/database/migrations/2023_07_13_120721_add_license_to_instance_settings.php index c32cd0f9a..6ecd5d971 100644 --- a/database/migrations/2023_07_13_120721_add_license_to_instance_settings.php +++ b/database/migrations/2023_07_13_120721_add_license_to_instance_settings.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_07_27_182013_smtp_discord_schemaless_to_normal.php b/database/migrations/2023_07_27_182013_smtp_discord_schemaless_to_normal.php index 2faa9f9ba..207d5e081 100644 --- a/database/migrations/2023_07_27_182013_smtp_discord_schemaless_to_normal.php +++ b/database/migrations/2023_07_27_182013_smtp_discord_schemaless_to_normal.php @@ -1,13 +1,12 @@ boolean('discord_notifications_status_changes')->default(true); }); $teams = Team::all(); - foreach($teams as $team) { + foreach ($teams as $team) { $team->smtp_enabled = data_get($team, 'smtp.enabled', false); $team->smtp_from_address = data_get($team, 'smtp.from_address'); $team->smtp_from_name = data_get($team, 'smtp.from_name'); @@ -46,15 +45,15 @@ public function up(): void $team->smtp_username = data_get($team, 'smtp.username'); $team->smtp_password = data_get($team, 'smtp.password'); $team->smtp_timeout = data_get($team, 'smtp.timeout'); - $team->smtp_notifications_test = data_get($team, 'smtp_notifications.test',true); - $team->smtp_notifications_deployments = data_get($team, 'smtp_notifications.deployments',false); - $team->smtp_notifications_status_changes = data_get($team, 'smtp_notifications.status_changes',false); + $team->smtp_notifications_test = data_get($team, 'smtp_notifications.test', true); + $team->smtp_notifications_deployments = data_get($team, 'smtp_notifications.deployments', false); + $team->smtp_notifications_status_changes = data_get($team, 'smtp_notifications.status_changes', false); $team->discord_enabled = data_get($team, 'discord.enabled', false); $team->discord_webhook_url = data_get($team, 'discord.webhook_url'); - $team->discord_notifications_test = data_get($team, 'discord_notifications.test',true); - $team->discord_notifications_deployments = data_get($team, 'discord_notifications.deployments',true); - $team->discord_notifications_status_changes = data_get($team, 'discord_notifications.status_changes',true); + $team->discord_notifications_test = data_get($team, 'discord_notifications.test', true); + $team->discord_notifications_deployments = data_get($team, 'discord_notifications.deployments', true); + $team->discord_notifications_status_changes = data_get($team, 'discord_notifications.status_changes', true); $team->save(); } @@ -78,7 +77,7 @@ public function up(): void $table->integer('smtp_timeout')->nullable(); }); $instance_settings = InstanceSettings::all(); - foreach($instance_settings as $instance_setting) { + foreach ($instance_settings as $instance_setting) { $instance_setting->smtp_enabled = data_get($instance_setting, 'smtp.enabled', false); $instance_setting->smtp_from_address = data_get($instance_setting, 'smtp.from_address'); $instance_setting->smtp_from_name = data_get($instance_setting, 'smtp.from_name'); @@ -108,7 +107,7 @@ public function down(): void $table->schemalessAttributes('discord_notifications'); }); $teams = Team::all(); - foreach($teams as $team) { + foreach ($teams as $team) { $team->smtp = [ 'enabled' => $team->smtp_enabled, 'from_address' => $team->smtp_from_address, @@ -190,4 +189,4 @@ public function down(): void $table->dropColumn('smtp_timeout'); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_08_07_073651_create_s3_storages_table.php b/database/migrations/2023_08_07_073651_create_s3_storages_table.php index cdda367a2..0a7415afb 100644 --- a/database/migrations/2023_08_07_073651_create_s3_storages_table.php +++ b/database/migrations/2023_08_07_073651_create_s3_storages_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -34,4 +33,4 @@ public function down(): void { Schema::dropIfExists('s3_storages'); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php b/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php index c159434e6..180d6382f 100644 --- a/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php +++ b/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php b/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php index 02d4c5935..2bd1c428c 100644 --- a/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php +++ b/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -25,4 +24,4 @@ public function down(): void $table->dropColumn('description'); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php b/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php index d24dbb446..2adf41b90 100644 --- a/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php +++ b/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php b/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php index f0bce760d..1a693eee9 100644 --- a/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php +++ b/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/seeders/ApplicationPreviewSeeder.php b/database/seeders/ApplicationPreviewSeeder.php index 512f1c990..764939073 100644 --- a/database/seeders/ApplicationPreviewSeeder.php +++ b/database/seeders/ApplicationPreviewSeeder.php @@ -2,11 +2,6 @@ namespace Database\Seeders; -use App\Models\Application; -use App\Models\ApplicationPreview; -use App\Models\Environment; -use App\Models\GithubApp; -use App\Models\StandaloneDocker; use Illuminate\Database\Seeder; class ApplicationPreviewSeeder extends Seeder diff --git a/database/seeders/ApplicationSeeder.php b/database/seeders/ApplicationSeeder.php index 9cffe6fbe..42997a708 100644 --- a/database/seeders/ApplicationSeeder.php +++ b/database/seeders/ApplicationSeeder.php @@ -4,12 +4,8 @@ use App\Data\ApplicationPreview; use App\Models\Application; -use App\Models\ApplicationSetting; -use App\Models\Environment; use App\Models\GithubApp; -use App\Models\LocalPersistentVolume; use App\Models\StandaloneDocker; -use App\Models\SwarmDocker; use Illuminate\Database\Seeder; class ApplicationSeeder extends Seeder @@ -38,4 +34,4 @@ public function run(): void 'source_type' => GithubApp::class ]); } -} \ No newline at end of file +} diff --git a/database/seeders/ApplicationSettingsSeeder.php b/database/seeders/ApplicationSettingsSeeder.php index 3ab5bd967..8e439fd16 100644 --- a/database/seeders/ApplicationSettingsSeeder.php +++ b/database/seeders/ApplicationSettingsSeeder.php @@ -3,11 +3,6 @@ namespace Database\Seeders; use App\Models\Application; -use App\Models\ApplicationSetting; -use App\Models\Environment; -use App\Models\GithubApp; -use App\Models\StandaloneDocker; -use App\Models\SwarmDocker; use Illuminate\Database\Seeder; class ApplicationSettingsSeeder extends Seeder diff --git a/database/seeders/DBSeeder.php b/database/seeders/DBSeeder.php index 35effa0c6..1e88129f8 100644 --- a/database/seeders/DBSeeder.php +++ b/database/seeders/DBSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use App\Models\Database; use App\Models\Environment; use App\Models\StandaloneDocker; use Illuminate\Database\Seeder; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 96209ade7..3ead195e4 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use App\Models\Environment; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder diff --git a/database/seeders/EnvironmentSeeder.php b/database/seeders/EnvironmentSeeder.php index 345bda5c5..0e980f22b 100644 --- a/database/seeders/EnvironmentSeeder.php +++ b/database/seeders/EnvironmentSeeder.php @@ -2,9 +2,6 @@ namespace Database\Seeders; -use App\Models\Environment; -use App\Models\Project; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class EnvironmentSeeder extends Seeder diff --git a/database/seeders/GitSeeder.php b/database/seeders/GitSeeder.php index ce426d162..c8dc3ab6d 100644 --- a/database/seeders/GitSeeder.php +++ b/database/seeders/GitSeeder.php @@ -3,9 +3,6 @@ namespace Database\Seeders; use App\Models\Git; -use App\Models\PrivateKey; -use App\Models\Project; -use App\Models\Team; use Illuminate\Database\Seeder; class GitSeeder extends Seeder diff --git a/database/seeders/GithubAppSeeder.php b/database/seeders/GithubAppSeeder.php index e2d1bb9c6..681017e6e 100644 --- a/database/seeders/GithubAppSeeder.php +++ b/database/seeders/GithubAppSeeder.php @@ -5,7 +5,6 @@ use App\Models\GithubApp; use App\Models\PrivateKey; use App\Models\Team; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class GithubAppSeeder extends Seeder diff --git a/database/seeders/GitlabAppSeeder.php b/database/seeders/GitlabAppSeeder.php index bf1833ae4..9a7165844 100644 --- a/database/seeders/GitlabAppSeeder.php +++ b/database/seeders/GitlabAppSeeder.php @@ -5,7 +5,6 @@ use App\Models\GitlabApp; use App\Models\PrivateKey; use App\Models\Team; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class GitlabAppSeeder extends Seeder diff --git a/database/seeders/KubernetesSeeder.php b/database/seeders/KubernetesSeeder.php index e43a8df60..f6a852e05 100644 --- a/database/seeders/KubernetesSeeder.php +++ b/database/seeders/KubernetesSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class KubernetesSeeder extends Seeder diff --git a/database/seeders/PrivateKeySeeder.php b/database/seeders/PrivateKeySeeder.php index 52785f164..d86f25fbc 100644 --- a/database/seeders/PrivateKeySeeder.php +++ b/database/seeders/PrivateKeySeeder.php @@ -3,9 +3,7 @@ namespace Database\Seeders; use App\Models\PrivateKey; -use App\Models\Server; use App\Models\Team; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class PrivateKeySeeder extends Seeder diff --git a/database/seeders/S3StorageSeeder.php b/database/seeders/S3StorageSeeder.php index 499510717..de7cef6dc 100644 --- a/database/seeders/S3StorageSeeder.php +++ b/database/seeders/S3StorageSeeder.php @@ -2,9 +2,8 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; -use Illuminate\Database\Seeder; use App\Models\S3Storage; +use Illuminate\Database\Seeder; class S3StorageSeeder extends Seeder { @@ -23,4 +22,4 @@ public function run(): void 'team_id' => 0, ]); } -} \ No newline at end of file +} diff --git a/database/seeders/ServerSeeder.php b/database/seeders/ServerSeeder.php index 82ab2552b..a781ca1de 100644 --- a/database/seeders/ServerSeeder.php +++ b/database/seeders/ServerSeeder.php @@ -2,9 +2,6 @@ namespace Database\Seeders; -use App\Data\ServerMetadata; -use App\Enums\ProxyStatus; -use App\Enums\ProxyTypes; use App\Models\PrivateKey; use App\Models\Server; use App\Models\Team; diff --git a/database/seeders/ServerSettingSeeder.php b/database/seeders/ServerSettingSeeder.php index fe366ba77..59fe07c99 100644 --- a/database/seeders/ServerSettingSeeder.php +++ b/database/seeders/ServerSettingSeeder.php @@ -3,7 +3,6 @@ namespace Database\Seeders; use App\Models\Server; -use App\Models\Team; use Illuminate\Database\Seeder; class ServerSettingSeeder extends Seeder diff --git a/database/seeders/ServiceSeeder.php b/database/seeders/ServiceSeeder.php index 360c946c5..c016d89e6 100644 --- a/database/seeders/ServiceSeeder.php +++ b/database/seeders/ServiceSeeder.php @@ -3,7 +3,6 @@ namespace Database\Seeders; use App\Models\Environment; -use App\Models\Service; use App\Models\StandaloneDocker; use Illuminate\Database\Seeder; diff --git a/database/seeders/StandaloneDockerSeeder.php b/database/seeders/StandaloneDockerSeeder.php index cbf32759f..8b1bfa76a 100644 --- a/database/seeders/StandaloneDockerSeeder.php +++ b/database/seeders/StandaloneDockerSeeder.php @@ -5,7 +5,6 @@ use App\Models\Destination; use App\Models\Server; use App\Models\StandaloneDocker; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class StandaloneDockerSeeder extends Seeder diff --git a/database/seeders/StandalonePostgresqlSeeder.php b/database/seeders/StandalonePostgresqlSeeder.php index 126f159e7..51f249f2a 100644 --- a/database/seeders/StandalonePostgresqlSeeder.php +++ b/database/seeders/StandalonePostgresqlSeeder.php @@ -2,10 +2,9 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; -use Illuminate\Database\Seeder; -use App\Models\StandalonePostgresql; use App\Models\StandaloneDocker; +use App\Models\StandalonePostgresql; +use Illuminate\Database\Seeder; class StandalonePostgresqlSeeder extends Seeder { diff --git a/database/seeders/SubscriptionSeeder.php b/database/seeders/SubscriptionSeeder.php index e76d793a3..03a5ed8f3 100644 --- a/database/seeders/SubscriptionSeeder.php +++ b/database/seeders/SubscriptionSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class SubscriptionSeeder extends Seeder diff --git a/database/seeders/SwarmDockerSeeder.php b/database/seeders/SwarmDockerSeeder.php index a9662a969..dc2934ead 100644 --- a/database/seeders/SwarmDockerSeeder.php +++ b/database/seeders/SwarmDockerSeeder.php @@ -4,9 +4,7 @@ use App\Models\Destination; use App\Models\Server; -use App\Models\StandaloneDocker; use App\Models\SwarmDocker; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class SwarmDockerSeeder extends Seeder diff --git a/database/seeders/WebhookSeeder.php b/database/seeders/WebhookSeeder.php index f226c715a..1d2ef1357 100644 --- a/database/seeders/WebhookSeeder.php +++ b/database/seeders/WebhookSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class WebhookSeeder extends Seeder diff --git a/other/logos/appwrite.svg b/other/logos/appwrite.svg index 7128b7b73..b5b8e4ab7 100644 --- a/other/logos/appwrite.svg +++ b/other/logos/appwrite.svg @@ -1,2 +1,14 @@ - - \ No newline at end of file + + + + + + diff --git a/public/index.php b/public/index.php index 1d69f3a28..f3c2ebcd3 100644 --- a/public/index.php +++ b/public/index.php @@ -16,7 +16,7 @@ | */ -if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) { +if (file_exists($maintenance = __DIR__ . '/../storage/framework/maintenance.php')) { require $maintenance; } @@ -31,7 +31,7 @@ | */ -require __DIR__.'/../vendor/autoload.php'; +require __DIR__ . '/../vendor/autoload.php'; /* |-------------------------------------------------------------------------- @@ -44,7 +44,7 @@ | */ -$app = require_once __DIR__.'/../bootstrap/app.php'; +$app = require_once __DIR__ . '/../bootstrap/app.php'; $kernel = $app->make(Kernel::class); diff --git a/public/svgs/external-link.svg b/public/svgs/external-link.svg index e0e47d694..c3c982ff0 100644 --- a/public/svgs/external-link.svg +++ b/public/svgs/external-link.svg @@ -1,6 +1,6 @@ -
Coolify
- +
@csrf + autofocus/> {{ __('auth.confirm_password') }} @if ($errors->any()) diff --git a/resources/views/auth/forgot-password.blade.php b/resources/views/auth/forgot-password.blade.php index 0a8bccff6..b89fed205 100644 --- a/resources/views/auth/forgot-password.blade.php +++ b/resources/views/auth/forgot-password.blade.php @@ -5,7 +5,7 @@
Coolify
- +
@@ -16,13 +16,15 @@
@csrf + label="{{ __('input.email') }}" autofocus/> {{ __('auth.forgot_password_send_email') }} @else
Transactional emails are not active on this instance.
See how to set it in our docs, or how to manually reset password.
+ href="https://docs.coollabs.io/coolify">docs, or how to + manually reset password. +
@endif @if ($errors->any())
diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index 0a66be609..d1a8fefd7 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -3,7 +3,7 @@
Coolify
- +

{{ __('auth.login') }}

@@ -17,33 +17,33 @@
@csrf @env('local') - + - - - {{ __('auth.forgot_password') }}? - - @else - - - @endenv + + + {{ __('auth.forgot_password') }}? + + @else + + + @endenv - {{ __('auth.login') }} - @if (!$is_registration_enabled) -
{{ __('auth.registration_disabled') }}
- @endif - @if ($errors->any()) -
- {{ __('auth.failed') }} -
- @endif - @if (session('status')) -
- {{ session('status') }} -
- @endif + {{ __('auth.login') }} + @if (!$is_registration_enabled) +
{{ __('auth.registration_disabled') }}
+ @endif + @if ($errors->any()) +
+ {{ __('auth.failed') }} +
+ @endif + @if (session('status')) +
+ {{ session('status') }} +
+ @endif
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php index 31003d2a9..3fafe8c3d 100644 --- a/resources/views/auth/register.blade.php +++ b/resources/views/auth/register.blade.php @@ -3,38 +3,38 @@
Coolify
- +
@csrf @env('local') - - -
- - -
- @else - - -
- - -
- @endenv - {{ __('auth.register') }} + + +
+ + +
+ @else + + +
+ + +
+ @endenv + {{ __('auth.register') }} @if ($errors->any())
diff --git a/resources/views/auth/reset-password.blade.php b/resources/views/auth/reset-password.blade.php index c5e1ab850..5a601f648 100644 --- a/resources/views/auth/reset-password.blade.php +++ b/resources/views/auth/reset-password.blade.php @@ -5,7 +5,7 @@
Coolify
- +

{{ __('auth.reset_password') }}

@@ -15,12 +15,12 @@ @csrf + label="{{ __('input.email') }}"/>
+ label="{{ __('input.password') }}" autofocus/> + label="{{ __('input.password.again') }}"/>
{{ __('auth.reset_password') }} diff --git a/resources/views/auth/two-factor-challenge.blade.php b/resources/views/auth/two-factor-challenge.blade.php index a5e645d7e..3bd7c8452 100644 --- a/resources/views/auth/two-factor-challenge.blade.php +++ b/resources/views/auth/two-factor-challenge.blade.php @@ -3,7 +3,7 @@
Coolify
- +
@@ -11,9 +11,9 @@