diff --git a/.ssh/known_hosts b/.ssh/known_hosts new file mode 100644 index 000000000..a59e3d0b4 --- /dev/null +++ b/.ssh/known_hosts @@ -0,0 +1 @@ +|1|TRkudHmvsBVekjyAfpo3EWrkQSs=|XdMLpIt2l32hhdSyWnDwMMlVBSI= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK/Ln1b72Lc5JtHRDiZd4lYyW7F5aVuJH42HdHXuYudT diff --git a/app/Actions/Server/UpdateCoolify.php b/app/Actions/Server/UpdateCoolify.php index 60d0f9a73..08740a8ed 100644 --- a/app/Actions/Server/UpdateCoolify.php +++ b/app/Actions/Server/UpdateCoolify.php @@ -17,9 +17,6 @@ public function __invoke(bool $force) $settings = InstanceSettings::get(); ray('Running InstanceAutoUpdateJob'); $localhost_name = 'localhost'; - if (is_dev()) { - $localhost_name = 'testing-local-docker-container'; - } $this->server = Server::where('name', $localhost_name)->firstOrFail(); $this->latest_version = get_latest_version_of_coolify(); $this->current_version = config('version'); diff --git a/app/Http/Controllers/ApplicationController.php b/app/Http/Controllers/ApplicationController.php index 9b87492e4..aa2787de7 100644 --- a/app/Http/Controllers/ApplicationController.php +++ b/app/Http/Controllers/ApplicationController.php @@ -12,7 +12,7 @@ class ApplicationController extends Controller public function configuration() { - $project = auth()->user()->currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { return redirect()->route('dashboard'); } @@ -29,7 +29,7 @@ public function configuration() public function deployments() { - $project = auth()->user()->currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { return redirect()->route('dashboard'); } @@ -49,7 +49,7 @@ public function deployment() { $deploymentUuid = request()->route('deployment_uuid'); - $project = auth()->user()->currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { return redirect()->route('dashboard'); } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 84da5de2e..d78e67505 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -58,7 +58,6 @@ public function dashboard() $resources += $project->applications->count(); $resources += $project->postgresqls->count(); } - return view('dashboard', [ 'servers' => $servers->count(), 'projects' => $projects->count(), @@ -66,10 +65,17 @@ public function dashboard() 's3s' => $s3s, ]); } + public function boarding() { + if (currentTeam()->boarding || is_dev()) { + return view('boarding'); + } else { + return redirect()->route('dashboard'); + } + } public function settings() { - if (is_instance_admin()) { + if (isInstanceAdmin()) { $settings = InstanceSettings::get(); $database = StandalonePostgresql::whereName('coolify-db')->first(); if ($database) { @@ -89,7 +95,7 @@ public function team() { $invitations = []; if (auth()->user()->isAdminFromSession()) { - $invitations = TeamInvitation::whereTeamId(auth()->user()->currentTeam()->id)->get(); + $invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get(); } return view('team.show', [ 'invitations' => $invitations, @@ -116,7 +122,7 @@ public function members() { $invitations = []; if (auth()->user()->isAdminFromSession()) { - $invitations = TeamInvitation::whereTeamId(auth()->user()->currentTeam()->id)->get(); + $invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get(); } return view('team.members', [ 'invitations' => $invitations, diff --git a/app/Http/Controllers/DatabaseController.php b/app/Http/Controllers/DatabaseController.php index bb6baf5ec..958d6d5ab 100644 --- a/app/Http/Controllers/DatabaseController.php +++ b/app/Http/Controllers/DatabaseController.php @@ -11,7 +11,7 @@ class DatabaseController extends Controller public function configuration() { - $project = auth()->user()->currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { return redirect()->route('dashboard'); } @@ -29,7 +29,7 @@ public function configuration() public function executions() { $backup_uuid = request()->route('backup_uuid'); - $project = auth()->user()->currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { return redirect()->route('dashboard'); } @@ -50,13 +50,13 @@ public function executions() 'database' => $database, 'backup' => $backup, 'executions' => $executions, - 's3s' => auth()->user()->currentTeam()->s3s, + 's3s' => currentTeam()->s3s, ]); } public function backups() { - $project = auth()->user()->currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { return redirect()->route('dashboard'); } @@ -70,7 +70,7 @@ public function backups() } return view('project.database.backups.all', [ 'database' => $database, - 's3s' => auth()->user()->currentTeam()->s3s, + 's3s' => currentTeam()->s3s, ]); } } diff --git a/app/Http/Controllers/MagicController.php b/app/Http/Controllers/MagicController.php index 515bc14d1..d7635fda0 100644 --- a/app/Http/Controllers/MagicController.php +++ b/app/Http/Controllers/MagicController.php @@ -41,7 +41,7 @@ public function newProject() { $project = Project::firstOrCreate( ['name' => request()->query('name') ?? generate_random_name()], - ['team_id' => auth()->user()->currentTeam()->id] + ['team_id' => currentTeam()->id] ); return response()->json([ 'project_uuid' => $project->uuid @@ -68,7 +68,7 @@ public function newTeam() ], ); auth()->user()->teams()->attach($team, ['role' => 'admin']); - session(['currentTeam' => $team]); + refreshSession(); return redirect(request()->header('Referer')); } } diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 2ad941e92..476d54437 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -18,7 +18,7 @@ public function all() public function edit() { $projectUuid = request()->route('project_uuid'); - $teamId = auth()->user()->currentTeam()->id; + $teamId = currentTeam()->id; $project = Project::where('team_id', $teamId)->where('uuid', $projectUuid)->first(); if (!$project) { return redirect()->route('dashboard'); @@ -29,7 +29,7 @@ public function edit() public function show() { $projectUuid = request()->route('project_uuid'); - $teamId = auth()->user()->currentTeam()->id; + $teamId = currentTeam()->id; $project = Project::where('team_id', $teamId)->where('uuid', $projectUuid)->first(); if (!$project) { @@ -44,7 +44,7 @@ public function new() $type = request()->query('type'); $destination_uuid = request()->query('destination'); - $project = auth()->user()->currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { return redirect()->route('dashboard'); } @@ -67,7 +67,7 @@ public function new() public function resources() { - $project = auth()->user()->currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (!$project) { return redirect()->route('dashboard'); } diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php index 2c2a34363..54b8c7a8c 100644 --- a/app/Http/Controllers/ServerController.php +++ b/app/Http/Controllers/ServerController.php @@ -12,14 +12,14 @@ class ServerController extends Controller public function new_server() { - if (!is_cloud() || is_instance_admin()) { + if (!is_cloud() || isInstanceAdmin()) { return view('server.create', [ 'limit_reached' => false, 'private_keys' => PrivateKey::ownedByCurrentTeam()->get(), ]); } - $servers = auth()->user()->currentTeam()->servers->count(); - $subscription = auth()->user()->currentTeam()?->subscription->type(); + $servers = currentTeam()->servers->count(); + $subscription = currentTeam()?->subscription->type(); $your_limit = config('constants.limits.server')[strtolower($subscription)]; $limit_reached = $servers >= $your_limit; diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 57b5edfec..eb93b6d35 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -39,6 +39,7 @@ class Kernel extends HttpKernel \Illuminate\Routing\Middleware\SubstituteBindings::class, \App\Http\Middleware\CheckForcePasswordReset::class, \App\Http\Middleware\SubscriptionValid::class, + \App\Http\Middleware\IsBoardingFlow::class, ], diff --git a/app/Http/Livewire/Boarding.php b/app/Http/Livewire/Boarding.php new file mode 100644 index 000000000..47dd072ba --- /dev/null +++ b/app/Http/Livewire/Boarding.php @@ -0,0 +1,147 @@ +privateKeyName = generate_random_name(); + $this->remoteServerName = generate_random_name(); + if (is_dev()) { + $this->privateKey = '-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk +hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA +AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV +uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== +-----END OPENSSH PRIVATE KEY-----'; + $this->privateKeyDescription = 'Created by Coolify'; + $this->remoteServerDescription = 'Created by Coolify'; + $this->remoteServerHost = 'coolify-testing-host'; + } + } + public function restartBoarding() + { + if ($this->createdServer) { + $this->createdServer->delete(); + } + if ($this->createdPrivateKey) { + $this->createdPrivateKey->delete(); + } + return redirect()->route('boarding'); + } + public function skipBoarding() + { + currentTeam()->update([ + 'show_boarding' => false + ]); + refreshSession(); + return redirect()->route('dashboard'); + } + public function setServer(string $type) + { + if ($type === 'localhost') { + $this->currentState = 'create-project'; + } elseif ($type === 'remote') { + $this->currentState = 'private-key'; + } + } + public function setPrivateKey(string $type) + { + $this->privateKeyType = $type; + $this->currentState = 'create-private-key'; + } + public function savePrivateKey() + { + $this->validate([ + 'privateKeyName' => 'required', + 'privateKey' => 'required', + ]); + $this->currentState = 'create-server'; + } + public function saveServer() + { + $this->validate([ + 'remoteServerName' => 'required', + 'remoteServerHost' => 'required', + 'remoteServerPort' => 'required', + 'remoteServerUser' => 'required', + ]); + if ($this->privateKeyType === 'create') { + $this->createNewPrivateKey(); + } + $this->privateKey = formatPrivateKey($this->privateKey); + $this->createdPrivateKey = PrivateKey::create([ + 'name' => $this->privateKeyName, + 'description' => $this->privateKeyDescription, + 'private_key' => $this->privateKey, + 'team_id' => currentTeam()->id + ]); + $this->createdServer = Server::create([ + 'name' => $this->remoteServerName, + 'ip' => $this->remoteServerHost, + 'port' => $this->remoteServerPort, + 'user' => $this->remoteServerUser, + 'description' => $this->remoteServerDescription, + 'private_key_id' => $this->createdPrivateKey->id, + 'team_id' => currentTeam()->id + ]); + try { + ['uptime' => $uptime, 'dockerVersion' => $dockerVersion] = validateServer($this->createdServer); + if (!$uptime) { + $this->createdServer->delete(); + $this->createdPrivateKey->delete(); + throw new \Exception('Server is not reachable.'); + } else { + $this->createdServer->settings->update([ + 'is_reachable' => true, + ]); + $this->emit('success', 'Server is reachable.'); + } + if ($dockerVersion) { + $this->emit('error', 'Docker is not installed on the server.'); + $this->currentState = 'install-docker'; + return; + } + ray($uptime, $dockerVersion); + } catch (\Exception $e) { + return general_error_handler(customErrorMessage: "Server is not reachable. Reason: {$e->getMessage()}", that: $this); + } + } + private function createNewPrivateKey() + { + $this->privateKeyName = generate_random_name(); + $this->privateKeyDescription = 'Created by Coolify'; + $this->privateKey = generateSSHKey(); + } + public function createNewProject() + { + Project::create([ + 'name' => generate_random_name(), + 'team_id' => currentTeam()->id + ]); + } +} diff --git a/app/Http/Livewire/Destination/New/StandaloneDocker.php b/app/Http/Livewire/Destination/New/StandaloneDocker.php index fa884ec37..f67180b69 100644 --- a/app/Http/Livewire/Destination/New/StandaloneDocker.php +++ b/app/Http/Livewire/Destination/New/StandaloneDocker.php @@ -67,7 +67,7 @@ public function submit() 'name' => $this->name, 'network' => $this->network, 'server_id' => $this->server_id, - 'team_id' => auth()->user()->currentTeam()->id + 'team_id' => currentTeam()->id ]); } $this->createNetworkAndAttachToProxy(); diff --git a/app/Http/Livewire/Notifications/DiscordSettings.php b/app/Http/Livewire/Notifications/DiscordSettings.php index 03cac4753..f9de6d662 100644 --- a/app/Http/Livewire/Notifications/DiscordSettings.php +++ b/app/Http/Livewire/Notifications/DiscordSettings.php @@ -41,10 +41,9 @@ public function submit() public function saveModel() { - ray($this->model); $this->model->save(); if (is_a($this->model, Team::class)) { - session(['currentTeam' => $this->model]); + refreshSession(); } $this->emit('success', 'Settings saved.'); } diff --git a/app/Http/Livewire/Notifications/EmailSettings.php b/app/Http/Livewire/Notifications/EmailSettings.php index eceb4e88b..a2887f989 100644 --- a/app/Http/Livewire/Notifications/EmailSettings.php +++ b/app/Http/Livewire/Notifications/EmailSettings.php @@ -59,7 +59,7 @@ public function copyFromInstanceSettings() { $settings = InstanceSettings::get(); if ($settings->smtp_enabled) { - $team = auth()->user()->currentTeam(); + $team = currentTeam(); $team->update([ 'smtp_enabled' => $settings->smtp_enabled, 'smtp_from_address' => $settings->smtp_from_address, @@ -74,7 +74,7 @@ public function copyFromInstanceSettings() ]); $this->decrypt(); if (is_a($team, Team::class)) { - session(['currentTeam' => $team]); + refreshSession(); } $this->model = $team; $this->emit('success', 'Settings saved.'); @@ -119,7 +119,7 @@ public function saveModel() $this->model->save(); $this->decrypt(); if (is_a($this->model, Team::class)) { - session(['currentTeam' => $this->model]); + refreshSession(); } $this->emit('success', 'Settings saved.'); } diff --git a/app/Http/Livewire/PrivateKey/Change.php b/app/Http/Livewire/PrivateKey/Change.php index 91d42bd7a..bd9332ca2 100644 --- a/app/Http/Livewire/PrivateKey/Change.php +++ b/app/Http/Livewire/PrivateKey/Change.php @@ -26,7 +26,7 @@ public function delete() try { if ($this->private_key->isEmpty()) { $this->private_key->delete(); - auth()->user()->currentTeam()->privateKeys = PrivateKey::where('team_id', auth()->user()->currentTeam()->id)->get(); + currentTeam()->privateKeys = PrivateKey::where('team_id', currentTeam()->id)->get(); return redirect()->route('private-key.all'); } $this->emit('error', 'This private key is in use and cannot be deleted. Please delete all servers, applications, and GitHub/GitLab apps that use this private key before deleting it.'); @@ -38,10 +38,7 @@ public function delete() public function changePrivateKey() { try { - $this->private_key->private_key = trim($this->private_key->private_key); - if (!str_ends_with($this->private_key->private_key, "\n")) { - $this->private_key->private_key .= "\n"; - } + $this->private_key->private_key = formatPrivateKey($this->private_key->private_key); $this->private_key->save(); refresh_server_connection($this->private_key); } catch (\Exception $e) { diff --git a/app/Http/Livewire/PrivateKey/Create.php b/app/Http/Livewire/PrivateKey/Create.php index 82218f4a5..d8d3cc41a 100644 --- a/app/Http/Livewire/PrivateKey/Create.php +++ b/app/Http/Livewire/PrivateKey/Create.php @@ -32,7 +32,7 @@ public function createPrivateKey() 'name' => $this->name, 'description' => $this->description, 'private_key' => $this->value, - 'team_id' => auth()->user()->currentTeam()->id + 'team_id' => currentTeam()->id ]); if ($this->from === 'server') { return redirect()->route('server.create'); diff --git a/app/Http/Livewire/Project/AddEmpty.php b/app/Http/Livewire/Project/AddEmpty.php index 1024bc66f..fc20f9850 100644 --- a/app/Http/Livewire/Project/AddEmpty.php +++ b/app/Http/Livewire/Project/AddEmpty.php @@ -25,7 +25,7 @@ public function submit() $project = Project::create([ 'name' => $this->name, 'description' => $this->description, - 'team_id' => auth()->user()->currentTeam()->id, + 'team_id' => currentTeam()->id, ]); return redirect()->route('project.show', $project->uuid); } catch (\Exception $e) { diff --git a/app/Http/Livewire/Project/Application/Source.php b/app/Http/Livewire/Project/Application/Source.php index 5affe9e45..801d533aa 100644 --- a/app/Http/Livewire/Project/Application/Source.php +++ b/app/Http/Livewire/Project/Application/Source.php @@ -29,7 +29,7 @@ public function mount() private function get_private_keys() { - $this->private_keys = PrivateKey::whereTeamId(auth()->user()->currentTeam()->id)->get()->reject(function ($key) { + $this->private_keys = PrivateKey::whereTeamId(currentTeam()->id)->get()->reject(function ($key) { return $key->id == $this->application->private_key_id; }); } diff --git a/app/Http/Livewire/Project/Database/CreateScheduledBackup.php b/app/Http/Livewire/Project/Database/CreateScheduledBackup.php index e3ea97735..9297f65f6 100644 --- a/app/Http/Livewire/Project/Database/CreateScheduledBackup.php +++ b/app/Http/Livewire/Project/Database/CreateScheduledBackup.php @@ -39,7 +39,7 @@ public function submit(): void 's3_storage_id' => $this->s3_storage_id, 'database_id' => $this->database->id, 'database_type' => $this->database->getMorphClass(), - 'team_id' => auth()->user()->currentTeam()->id, + 'team_id' => currentTeam()->id, ]); $this->emit('refreshScheduledBackups'); } catch (\Exception $e) { diff --git a/app/Http/Livewire/Project/New/EmptyProject.php b/app/Http/Livewire/Project/New/EmptyProject.php index e77ab983e..9dba4338b 100644 --- a/app/Http/Livewire/Project/New/EmptyProject.php +++ b/app/Http/Livewire/Project/New/EmptyProject.php @@ -11,7 +11,7 @@ public function createEmptyProject() { $project = Project::create([ 'name' => generate_random_name(), - 'team_id' => auth()->user()->currentTeam()->id, + 'team_id' => currentTeam()->id, ]); return redirect()->route('project.show', ['project_uuid' => $project->uuid, 'environment_name' => 'production']); } diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php index a1f275f32..a2ccd5298 100644 --- a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php +++ b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php @@ -55,7 +55,7 @@ public function mount() } $this->parameters = get_route_parameters(); $this->query = request()->query(); - $this->private_keys = PrivateKey::where('team_id', auth()->user()->currentTeam()->id)->where('id', '!=', 0)->get(); + $this->private_keys = PrivateKey::where('team_id', currentTeam()->id)->where('id', '!=', 0)->get(); } public function instantSave() diff --git a/app/Http/Livewire/Server/Form.php b/app/Http/Livewire/Server/Form.php index 4dcebc101..290c06dd7 100644 --- a/app/Http/Livewire/Server/Form.php +++ b/app/Http/Livewire/Server/Form.php @@ -42,7 +42,7 @@ public function mount() public function installDocker() { - $activity = resolve(InstallDocker::class)($this->server, auth()->user()->currentTeam()); + $activity = resolve(InstallDocker::class)($this->server, currentTeam()); $this->emit('newMonitorActivity', $activity->id); } diff --git a/app/Http/Livewire/Server/New/ByIp.php b/app/Http/Livewire/Server/New/ByIp.php index c4f340413..e6813a55f 100644 --- a/app/Http/Livewire/Server/New/ByIp.php +++ b/app/Http/Livewire/Server/New/ByIp.php @@ -65,7 +65,7 @@ public function submit() 'ip' => $this->ip, 'user' => $this->user, 'port' => $this->port, - 'team_id' => auth()->user()->currentTeam()->id, + 'team_id' => currentTeam()->id, 'private_key_id' => $this->private_key_id, ]); $server->settings->is_part_of_swarm = $this->is_part_of_swarm; diff --git a/app/Http/Livewire/Settings/Backup.php b/app/Http/Livewire/Settings/Backup.php index fcb105fd4..263db027d 100644 --- a/app/Http/Livewire/Settings/Backup.php +++ b/app/Http/Livewire/Settings/Backup.php @@ -65,7 +65,7 @@ public function add_coolify_database() 'frequency' => '0 0 * * *', 'database_id' => $this->database->id, 'database_type' => 'App\Models\StandalonePostgresql', - 'team_id' => auth()->user()->currentTeam()->id, + 'team_id' => currentTeam()->id, ]); $this->database->refresh(); $this->backup->refresh(); diff --git a/app/Http/Livewire/Source/Github/Create.php b/app/Http/Livewire/Source/Github/Create.php index 862964c45..4d6f8b26b 100644 --- a/app/Http/Livewire/Source/Github/Create.php +++ b/app/Http/Livewire/Source/Github/Create.php @@ -40,7 +40,7 @@ public function createGitHubApp() 'custom_user' => $this->custom_user, 'custom_port' => $this->custom_port, 'is_system_wide' => $this->is_system_wide, - 'team_id' => auth()->user()->currentTeam()->id, + 'team_id' => currentTeam()->id, ]); redirect()->route('source.github.show', ['github_app_uuid' => $github_app->uuid]); } catch (\Exception $e) { diff --git a/app/Http/Livewire/Subscription/Actions.php b/app/Http/Livewire/Subscription/Actions.php index 588a0521c..6c74880b7 100644 --- a/app/Http/Livewire/Subscription/Actions.php +++ b/app/Http/Livewire/Subscription/Actions.php @@ -10,7 +10,7 @@ class Actions extends Component public function cancel() { try { - $subscription_id = auth()->user()->currentTeam()->subscription->lemon_subscription_id; + $subscription_id = currentTeam()->subscription->lemon_subscription_id; if (!$subscription_id) { throw new \Exception('No subscription found'); } @@ -37,7 +37,7 @@ public function cancel() public function resume() { try { - $subscription_id = auth()->user()->currentTeam()->subscription->lemon_subscription_id; + $subscription_id = currentTeam()->subscription->lemon_subscription_id; if (!$subscription_id) { throw new \Exception('No subscription found'); } diff --git a/app/Http/Livewire/Team/Create.php b/app/Http/Livewire/Team/Create.php index 6c1c71580..bd2c24313 100644 --- a/app/Http/Livewire/Team/Create.php +++ b/app/Http/Livewire/Team/Create.php @@ -29,7 +29,7 @@ public function submit() 'personal_team' => false, ]); auth()->user()->teams()->attach($team, ['role' => 'admin']); - session(['currentTeam' => $team]); + refreshSession(); return redirect()->route('team.show'); } catch (\Throwable $th) { return general_error_handler($th, $this); diff --git a/app/Http/Livewire/Team/Delete.php b/app/Http/Livewire/Team/Delete.php index d14e82ccc..5e206704b 100644 --- a/app/Http/Livewire/Team/Delete.php +++ b/app/Http/Livewire/Team/Delete.php @@ -9,7 +9,7 @@ class Delete extends Component { public function delete() { - $currentTeam = auth()->user()->currentTeam(); + $currentTeam = currentTeam(); $currentTeam->delete(); $team = auth()->user()->teams()->first(); @@ -24,7 +24,7 @@ public function delete() } }); - session(['currentTeam' => $team]); + refreshSession(); return redirect()->route('team.show'); } } diff --git a/app/Http/Livewire/Team/Form.php b/app/Http/Livewire/Team/Form.php index eedd60c83..caa6d2c9e 100644 --- a/app/Http/Livewire/Team/Form.php +++ b/app/Http/Livewire/Team/Form.php @@ -19,7 +19,7 @@ class Form extends Component public function mount() { - $this->team = auth()->user()->currentTeam(); + $this->team = currentTeam(); } public function submit() @@ -27,7 +27,7 @@ public function submit() $this->validate(); try { $this->team->save(); - session(['currentTeam' => $this->team]); + refreshSession(); $this->emit('reloadWindow'); } catch (\Throwable $th) { return general_error_handler($th, $this); diff --git a/app/Http/Livewire/Team/Invitations.php b/app/Http/Livewire/Team/Invitations.php index ba0b654aa..ba6c1e91f 100644 --- a/app/Http/Livewire/Team/Invitations.php +++ b/app/Http/Livewire/Team/Invitations.php @@ -18,6 +18,6 @@ public function deleteInvitation(int $invitation_id) public function refreshInvitations() { - $this->invitations = TeamInvitation::whereTeamId(auth()->user()->currentTeam()->id)->get(); + $this->invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get(); } } diff --git a/app/Http/Livewire/Team/InviteLink.php b/app/Http/Livewire/Team/InviteLink.php index ddbe75182..aaf22f0e8 100644 --- a/app/Http/Livewire/Team/InviteLink.php +++ b/app/Http/Livewire/Team/InviteLink.php @@ -35,9 +35,9 @@ private function generate_invite_link(bool $isEmail = false) return general_error_handler(that: $this, customErrorMessage: "$this->email must be registered first (or activate transactional emails to invite via email)."); } - $member_emails = auth()->user()->currentTeam()->members()->get()->pluck('email'); + $member_emails = currentTeam()->members()->get()->pluck('email'); if ($member_emails->contains($this->email)) { - return general_error_handler(that: $this, customErrorMessage: "$this->email is already a member of " . auth()->user()->currentTeam()->name . "."); + return general_error_handler(that: $this, customErrorMessage: "$this->email is already a member of " . currentTeam()->name . "."); } $invitation = TeamInvitation::whereEmail($this->email); @@ -53,7 +53,7 @@ private function generate_invite_link(bool $isEmail = false) } TeamInvitation::firstOrCreate([ - 'team_id' => auth()->user()->currentTeam()->id, + 'team_id' => currentTeam()->id, 'uuid' => $uuid, 'email' => $this->email, 'role' => $this->role, diff --git a/app/Http/Livewire/Team/Member.php b/app/Http/Livewire/Team/Member.php index 237d38818..df8fcd7af 100644 --- a/app/Http/Livewire/Team/Member.php +++ b/app/Http/Livewire/Team/Member.php @@ -11,19 +11,19 @@ class Member extends Component public function makeAdmin() { - $this->member->teams()->updateExistingPivot(auth()->user()->currentTeam()->id, ['role' => 'admin']); + $this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => 'admin']); $this->emit('reloadWindow'); } public function makeReadonly() { - $this->member->teams()->updateExistingPivot(auth()->user()->currentTeam()->id, ['role' => 'member']); + $this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => 'member']); $this->emit('reloadWindow'); } public function remove() { - $this->member->teams()->detach(auth()->user()->currentTeam()); + $this->member->teams()->detach(currentTeam()); $this->emit('reloadWindow'); } } diff --git a/app/Http/Livewire/Team/Storage/Create.php b/app/Http/Livewire/Team/Storage/Create.php index ed7d277fb..52ce3779d 100644 --- a/app/Http/Livewire/Team/Storage/Create.php +++ b/app/Http/Livewire/Team/Storage/Create.php @@ -62,7 +62,7 @@ public function submit() } else { $this->storage->endpoint = $this->endpoint; } - $this->storage->team_id = auth()->user()->currentTeam()->id; + $this->storage->team_id = currentTeam()->id; $this->storage->testConnection(); $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); $this->storage->save(); diff --git a/app/Http/Middleware/IsBoardingFlow.php b/app/Http/Middleware/IsBoardingFlow.php new file mode 100644 index 000000000..e13e71f31 --- /dev/null +++ b/app/Http/Middleware/IsBoardingFlow.php @@ -0,0 +1,28 @@ +path(), $allowed_paths)) { + return redirect('boarding'); + } + return $next($request); + } +} diff --git a/app/Http/Middleware/SubscriptionValid.php b/app/Http/Middleware/SubscriptionValid.php index f84e6eede..01bd7a0e5 100644 --- a/app/Http/Middleware/SubscriptionValid.php +++ b/app/Http/Middleware/SubscriptionValid.php @@ -17,8 +17,7 @@ public function handle(Request $request, Closure $next): Response return $next($request); } } - $is_instance_admin = is_instance_admin(); - if ($is_instance_admin) { + if (isInstanceAdmin()) { return $next($request); } diff --git a/app/Models/EnvironmentVariable.php b/app/Models/EnvironmentVariable.php index bb4a5ca47..62a08c87f 100644 --- a/app/Models/EnvironmentVariable.php +++ b/app/Models/EnvironmentVariable.php @@ -41,7 +41,7 @@ protected function value(): Attribute private function get_environment_variables(string $environment_variable): string|null { - // $team_id = auth()->user()->currentTeam()->id; + // $team_id = currentTeam()->id; if (str_contains(trim($environment_variable), '{{') && str_contains(trim($environment_variable), '}}')) { $environment_variable = preg_replace('/\s+/', '', $environment_variable); $environment_variable = str_replace('{{', '', $environment_variable); diff --git a/app/Models/GithubApp.php b/app/Models/GithubApp.php index 74462e8d7..c4cd3568d 100644 --- a/app/Models/GithubApp.php +++ b/app/Models/GithubApp.php @@ -19,12 +19,12 @@ class GithubApp extends BaseModel static public function public() { - return GithubApp::whereTeamId(auth()->user()->currentTeam()->id)->whereisPublic(true)->whereNotNull('app_id')->get(); + return GithubApp::whereTeamId(currentTeam()->id)->whereisPublic(true)->whereNotNull('app_id')->get(); } static public function private() { - return GithubApp::whereTeamId(auth()->user()->currentTeam()->id)->whereisPublic(false)->whereNotNull('app_id')->get(); + return GithubApp::whereTeamId(currentTeam()->id)->whereisPublic(false)->whereNotNull('app_id')->get(); } protected static function booted(): void diff --git a/app/Models/PrivateKey.php b/app/Models/PrivateKey.php index 4d59e9ca8..d4fd0bfa2 100644 --- a/app/Models/PrivateKey.php +++ b/app/Models/PrivateKey.php @@ -16,7 +16,7 @@ class PrivateKey extends BaseModel static public function ownedByCurrentTeam(array $select = ['*']) { $selectArray = collect($select)->concat(['id']); - return PrivateKey::whereTeamId(auth()->user()->currentTeam()->id)->select($selectArray->all()); + return PrivateKey::whereTeamId(currentTeam()->id)->select($selectArray->all()); } public function isEmpty() diff --git a/app/Models/Project.php b/app/Models/Project.php index a50dde167..9bcd2a0fe 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -4,16 +4,11 @@ class Project extends BaseModel { - protected $fillable = [ - 'name', - 'description', - 'team_id', - 'project_id' - ]; + protected $guarded = []; static public function ownedByCurrentTeam() { - return Project::whereTeamId(auth()->user()->currentTeam()->id)->orderBy('name'); + return Project::whereTeamId(currentTeam()->id)->orderBy('name'); } protected static function booted() diff --git a/app/Models/S3Storage.php b/app/Models/S3Storage.php index 5cd2f1318..cbcdb97a9 100644 --- a/app/Models/S3Storage.php +++ b/app/Models/S3Storage.php @@ -17,7 +17,7 @@ class S3Storage extends BaseModel static public function ownedByCurrentTeam(array $select = ['*']) { $selectArray = collect($select)->concat(['id']); - return S3Storage::whereTeamId(auth()->user()->currentTeam()->id)->select($selectArray->all())->orderBy('name'); + return S3Storage::whereTeamId(currentTeam()->id)->select($selectArray->all())->orderBy('name'); } public function awsUrl() diff --git a/app/Models/Server.php b/app/Models/Server.php index 1d8ea0f77..d14d5f974 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -33,7 +33,7 @@ static public function isReachable() static public function ownedByCurrentTeam(array $select = ['*']) { - $teamId = auth()->user()->currentTeam()->id; + $teamId = currentTeam()->id; $selectArray = collect($select)->concat(['id']); return Server::whereTeamId($teamId)->with('settings')->select($selectArray->all())->orderBy('name'); } diff --git a/app/Models/User.php b/app/Models/User.php index b048ef9e6..8cd5b0a56 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -22,6 +22,7 @@ class User extends Authenticatable implements SendsEmail protected $casts = [ 'email_verified_at' => 'datetime', 'force_password_reset' => 'boolean', + 'show_boarding' => 'boolean', ]; protected static function boot() @@ -31,6 +32,7 @@ protected static function boot() $team = [ 'name' => $user->name . "'s Team", 'personal_team' => true, + 'show_boarding' => true, ]; if ($user->id === 0) { $team['id'] = 0; @@ -102,7 +104,7 @@ public function currentTeam() public function otherTeams() { - $team_id = auth()->user()->currentTeam()->id; + $team_id = currentTeam()->id; return auth()->user()->teams->filter(function ($team) use ($team_id) { return $team->id != $team_id; }); @@ -113,13 +115,6 @@ public function role() if ($this->teams()->where('team_id', 0)->first()) { return 'admin'; } - return $this->teams()->where('team_id', auth()->user()->currentTeam()->id)->first()->pivot->role; - } - - public function resources() - { - $team_id = auth()->user()->currentTeam()->id; - $data = Application::where('team_id', $team_id)->get(); - return $data; + return $this->teams()->where('team_id', currentTeam()->id)->first()->pivot->role; } } diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index ecc679b3f..86e11bcf3 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -66,8 +66,6 @@ function get_private_key_for_server(Server $server) function save_private_key_for_server(Server $server) { if (data_get($server, 'privateKey.private_key') === null) { - $server->settings->is_reachable = false; - $server->settings->save(); throw new \Exception("Server {$server->name} does not have a private key"); } $temp_file = "id.root@{$server->ip}"; @@ -159,8 +157,8 @@ function refresh_server_connection(PrivateKey $private_key) // Delete the old ssh mux file to force a new one to be created Storage::disk('ssh-mux')->delete($server->muxFilename()); // check if user is authenticated - if (auth()?->user()?->currentTeam()->id) { - auth()->user()->currentTeam()->privateKeys = PrivateKey::where('team_id', auth()->user()->currentTeam()->id)->get(); + if (currentTeam()->id) { + currentTeam()->privateKeys = PrivateKey::where('team_id', currentTeam()->id)->get(); } } } diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 4b470cb48..d02522245 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -14,6 +14,7 @@ use Nubs\RandomNameGenerator\All; use Poliander\Cron\CronExpression; use Visus\Cuid2\Cuid2; +use phpseclib3\Crypt\RSA; function application_configuration_dir(): string { @@ -35,11 +36,25 @@ function generate_readme_file(string $name, string $updated_at): string return "Resource name: $name\nLatest Deployment Date: $updated_at"; } -function is_instance_admin() +function isInstanceAdmin() { - return auth()->user()?->isInstanceAdmin(); + return auth()?->user()?->isInstanceAdmin() ?? false; } +function currentTeam() +{ + return auth()?->user()?->currentTeam() ?? null; +} + +function showBoarding(): bool +{ + return currentTeam()->show_boarding ?? false; +} +function refreshSession(): void +{ + $team = currentTeam(); + session(['currentTeam' => $team]); +} function general_error_handler(Throwable | null $err = null, $that = null, $isJson = false, $customErrorMessage = null): mixed { try { @@ -97,7 +112,21 @@ function generate_random_name(): string $cuid = new Cuid2(7); return Str::kebab("{$generator->getName()}-$cuid"); } - +function generateSSHKey() +{ + $key = RSA::createKey(); + return [ + 'private' => $key->toString('PKCS1'), + 'public' => $key->getPublicKey()->toString('OpenSSH',['comment' => 'coolify-generated-ssh-key']) + ]; +} +function formatPrivateKey(string $privateKey) { + $privateKey = trim($privateKey); + if (!str_ends_with($privateKey, "\n")) { + $privateKey .= "\n"; + } + return $privateKey; +} function generate_application_name(string $git_repository, string $git_branch): string { $cuid = new Cuid2(7); diff --git a/bootstrap/helpers/subscriptions.php b/bootstrap/helpers/subscriptions.php index 90d0947ad..5cb17d588 100644 --- a/bootstrap/helpers/subscriptions.php +++ b/bootstrap/helpers/subscriptions.php @@ -9,7 +9,7 @@ function getSubscriptionLink($type) return null; } $user_id = auth()->user()->id; - $team_id = auth()->user()->currentTeam()->id ?? null; + $team_id = currentTeam()->id ?? null; $email = auth()->user()->email ?? null; $name = auth()->user()->name ?? null; $url = "https://store.coollabs.io/checkout/buy/$checkout_id?"; @@ -30,27 +30,27 @@ function getSubscriptionLink($type) function getPaymentLink() { - return auth()->user()->currentTeam()->subscription->lemon_update_payment_menthod_url; + return 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'); + return Carbon::parse(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'); + return Carbon::parse(currentTeam()->subscription->lemon_renews_at)->format('Y-M-d H:i:s'); } function is_subscription_active() { - $team = auth()->user()?->currentTeam(); + $team = currentTeam(); if (!$team) { return false; } - if (is_instance_admin()) { + if (isInstanceAdmin()) { return true; } $subscription = $team?->subscription; @@ -64,11 +64,11 @@ function is_subscription_active() } function is_subscription_in_grace_period() { - $team = auth()->user()?->currentTeam(); + $team = currentTeam(); if (!$team) { return false; } - if (is_instance_admin()) { + if (isInstanceAdmin()) { return true; } $subscription = $team?->subscription; diff --git a/composer.json b/composer.json index c43f5d09c..fd8a5eb01 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ "livewire/livewire": "^v2.12.3", "masmerise/livewire-toaster": "^1.2", "nubs/random-name-generator": "^2.2", + "phpseclib/phpseclib": "~3.0", "poliander/cron": "^3.0", "resend/resend-laravel": "^0.5.0", "sentry/sentry-laravel": "^3.4", diff --git a/composer.lock b/composer.lock index a64169d6e..cf0183f12 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "15eb89e93c667bb63f48ef548ed38bed", + "content-hash": "a4143cdb58c02a0490f9aa03d05b8e9a", "packages": [ { "name": "aws/aws-crt-php", @@ -3875,6 +3875,56 @@ }, "time": "2022-06-14T06:56:20+00:00" }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, { "name": "php-http/client-common", "version": "2.7.0", @@ -4446,6 +4496,116 @@ ], "time": "2023-02-25T19:38:58+00:00" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.21", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "4580645d3fc05c189024eb3b834c6c1e4f0f30a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4580645d3fc05c189024eb3b834c6c1e4f0f30a1", + "reference": "4580645d3fc05c189024eb3b834c6c1e4f0f30a1", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.21" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2023-07-09T15:24:48+00:00" + }, { "name": "phpstan/phpdoc-parser", "version": "1.23.1", diff --git a/database/migrations/2023_08_22_071048_add_boarding_to_teams.php b/database/migrations/2023_08_22_071048_add_boarding_to_teams.php new file mode 100644 index 000000000..0fe2062e3 --- /dev/null +++ b/database/migrations/2023_08_22_071048_add_boarding_to_teams.php @@ -0,0 +1,28 @@ +boolean('show_boarding')->default(false); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('teams', function (Blueprint $table) { + $table->dropColumn('show_boarding'); + }); + } +}; diff --git a/database/seeders/ServerSeeder.php b/database/seeders/ServerSeeder.php index 77a4516e5..f201862f0 100644 --- a/database/seeders/ServerSeeder.php +++ b/database/seeders/ServerSeeder.php @@ -11,8 +11,8 @@ public function run(): void { Server::create([ 'id' => 0, - 'name' => "testing-local-docker-container", - 'description' => "This is a test docker container", + 'name' => "localhost", + 'description' => "This is a test docker container in development mode", 'ip' => "coolify-testing-host", 'team_id' => 0, 'private_key_id' => 0, diff --git a/package.json b/package.json index ed81d6a26..81e0dd5a8 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "private": true, + "type": "module", "scripts": { "dev": "vite", "build": "vite build" @@ -20,4 +21,4 @@ "daisyui": "3.2.1", "tailwindcss-scrollbar": "0.1.0" } -} \ No newline at end of file +} diff --git a/postcss.config.js b/postcss.config.cjs similarity index 100% rename from postcss.config.js rename to postcss.config.cjs diff --git a/resources/css/app.css b/resources/css/app.css index b5f58fc74..2e0f079ee 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -53,7 +53,7 @@ .icon:hover { @apply text-white; } .box { - @apply flex items-center justify-center p-2 transition-colors rounded min-h-12 bg-coolgray-200 hover:bg-coollabs-100 hover:text-white hover:no-underline; + @apply flex items-center justify-center p-2 transition-colors rounded cursor-pointer min-h-12 bg-coolgray-200 hover:bg-coollabs-100 hover:text-white hover:no-underline; } .lds-heart { diff --git a/resources/js/components/MagicBar.vue b/resources/js/components/MagicBar.vue index f0203b885..a0b08c283 100644 --- a/resources/js/components/MagicBar.vue +++ b/resources/js/components/MagicBar.vue @@ -53,12 +53,12 @@ {{ sequenceState.sequence[sequenceState.currentActionIndex] }} name will be: - {{ search - }} + + {{ sequenceState.sequence[sequenceState.currentActionIndex] }} name will be: - randomly generated (type to change) + diff --git a/resources/views/boarding.blade.php b/resources/views/boarding.blade.php new file mode 100644 index 000000000..d089e0650 --- /dev/null +++ b/resources/views/boarding.blade.php @@ -0,0 +1,3 @@ + + + diff --git a/resources/views/components/boarding-step.blade.php b/resources/views/components/boarding-step.blade.php new file mode 100644 index 000000000..4776f3365 --- /dev/null +++ b/resources/views/components/boarding-step.blade.php @@ -0,0 +1,25 @@ +
+
+

{{$title}}

+
+ @isset($question) +

+ {{$question}} +

+ @endisset +
+ @if($actions) +
+ {{$actions}} +
+ @endif +
+ @if($explanation) +
+

Explanation

+
+ {{$explanation}} +
+
+ @endif +
diff --git a/resources/views/components/forms/input.blade.php b/resources/views/components/forms/input.blade.php index a12366238..2abc8a91e 100644 --- a/resources/views/components/forms/input.blade.php +++ b/resources/views/components/forms/input.blade.php @@ -2,7 +2,7 @@ @if ($label)