diff --git a/README.md b/README.md index 6e6d80c59..3a211d4b1 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ Special thanks to our biggest sponsors, [CCCareers](https://cccareers.org/) and CryptoJobsList typebot BC Direct +UXWizz Corentin Clichy Corentin Clichy Niklas Lausch diff --git a/app/Actions/Database/StartDatabaseProxy.php b/app/Actions/Database/StartDatabaseProxy.php index 500798d30..2a86ab913 100644 --- a/app/Actions/Database/StartDatabaseProxy.php +++ b/app/Actions/Database/StartDatabaseProxy.php @@ -25,7 +25,8 @@ class StartDatabaseProxy $proxyContainerName = "{$database->uuid}-proxy"; if ($database->getMorphClass() === 'App\Models\ServiceDatabase') { $databaseType = $database->databaseType(); - $network = data_get($database, 'service.destination.network'); + // $connectPredefined = data_get($database, 'service.connect_to_docker_network'); + $network = $database->service->uuid; $server = data_get($database, 'service.destination.server'); $proxyContainerName = "{$database->service->uuid}-proxy"; switch ($databaseType) { @@ -124,6 +125,7 @@ class StartDatabaseProxy $dockercompose_base64 = base64_encode(Yaml::dump($docker_compose, 4, 2)); $nginxconf_base64 = base64_encode($nginxconf); $dockerfile_base64 = base64_encode($dockerfile); + instant_remote_process(["docker rm -f $proxyContainerName"], $server, false); instant_remote_process([ "mkdir -p $configuration_dir", "echo '{$dockerfile_base64}' | base64 -d > $configuration_dir/Dockerfile", diff --git a/app/Actions/Database/StopDatabaseProxy.php b/app/Actions/Database/StopDatabaseProxy.php index fc18985f1..6582da34e 100644 --- a/app/Actions/Database/StopDatabaseProxy.php +++ b/app/Actions/Database/StopDatabaseProxy.php @@ -17,10 +17,12 @@ class StopDatabaseProxy public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|ServiceDatabase $database) { $server = data_get($database, 'destination.server'); + $uuid = $database->uuid; if ($database->getMorphClass() === 'App\Models\ServiceDatabase') { + $uuid = $database->service->uuid; $server = data_get($database, 'service.server'); } - instant_remote_process(["docker rm -f {$database->uuid}-proxy"], $server); + instant_remote_process(["docker rm -f {$uuid}-proxy"], $server); $database->is_public = false; $database->save(); } diff --git a/app/Console/Commands/Horizon.php b/app/Console/Commands/Horizon.php new file mode 100644 index 000000000..8dd64a246 --- /dev/null +++ b/app/Console/Commands/Horizon.php @@ -0,0 +1,21 @@ +info('Horizon is enabled. Starting.'); + $this->call('horizon'); + exit(0); + } else { + exit(0); + } + } +} diff --git a/app/Console/Commands/Scheduler.php b/app/Console/Commands/Scheduler.php new file mode 100644 index 000000000..eab623802 --- /dev/null +++ b/app/Console/Commands/Scheduler.php @@ -0,0 +1,21 @@ +info('Scheduler is enabled. Starting.'); + $this->call('schedule:work'); + exit(0); + } else { + exit(0); + } + } +} diff --git a/app/Http/Controllers/OauthController.php b/app/Http/Controllers/OauthController.php new file mode 100644 index 000000000..7d917e5a6 --- /dev/null +++ b/app/Http/Controllers/OauthController.php @@ -0,0 +1,35 @@ +redirect(); + } + + public function callback(string $provider) + { + try { + $oauthUser = get_socialite_provider($provider)->user(); + $user = User::whereEmail($oauthUser->email)->first(); + if (!$user) { + $user = User::create([ + 'name' => $oauthUser->name, + 'email' => $oauthUser->email, + ]); + } + Auth::login($user); + return redirect('/'); + } catch (\Exception $e) { + ray($e->getMessage()); + return redirect()->route('login')->withErrors([__('auth.failed.callback')]); + } + } +} diff --git a/app/Http/Livewire/Server/New/ByIp.php b/app/Http/Livewire/Server/New/ByIp.php new file mode 100644 index 000000000..e69de29bb diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index a27800ee3..3c7ea68db 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -298,6 +298,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted "ignore_errors" => true, ] ); + + // $this->execute_remote_command( // [ // "docker image prune -f >/dev/null 2>&1", @@ -305,6 +307,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted // "ignore_errors" => true, // ] // ); + + ApplicationStatusChanged::dispatch(data_get($this->application, 'environment.project.team.id')); } } @@ -417,7 +421,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted "docker network connect {$networkId} coolify-proxy || true", "hidden" => true, "ignore_errors" => true ]); } - $this->write_deployment_configurations(); // Start compose file if ($this->application->settings->is_raw_compose_deployment_enabled) { @@ -425,7 +428,9 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $this->execute_remote_command( [executeInDocker($this->deployment_uuid, "cd {$this->workdir} && {$this->docker_compose_custom_start_command}"), "hidden" => true], ); + $this->write_deployment_configurations(); } else { + $this->write_deployment_configurations(); $server_workdir = $this->application->workdir(); ray("SOURCE_COMMIT={$this->commit} docker compose --project-directory {$server_workdir} -f {$server_workdir}{$this->docker_compose_location} up -d"); $this->execute_remote_command( @@ -437,14 +442,15 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $this->execute_remote_command( [executeInDocker($this->deployment_uuid, "cd {$this->basedir} && {$this->docker_compose_custom_start_command}"), "hidden" => true], ); + $this->write_deployment_configurations(); } else { $this->execute_remote_command( [executeInDocker($this->deployment_uuid, "SOURCE_COMMIT={$this->commit} docker compose --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} up -d"), "hidden" => true], ); + $this->write_deployment_configurations(); } } - $this->application_deployment_queue->addLogEntry("New container started."); } private function deploy_dockerfile_buildpack() @@ -822,6 +828,10 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted } private function deploy_pull_request() { + if ($this->application->build_pack === 'dockercompose') { + $this->deploy_docker_compose_buildpack(); + return; + } if ($this->use_build_server) { $this->server = $this->build_server; } diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 68035a258..b40826f97 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -8,6 +8,7 @@ use App\Actions\Proxy\StartProxy; use App\Actions\Shared\ComplexStatusCheck; use App\Models\ApplicationPreview; use App\Models\Server; +use App\Models\ServiceDatabase; use App\Notifications\Container\ContainerRestarted; use App\Notifications\Container\ContainerStopped; use Illuminate\Bus\Queueable; @@ -149,31 +150,63 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted } } else { $uuid = data_get($labels, 'com.docker.compose.service'); + $type = data_get($labels, 'coolify.type'); + if ($uuid) { - $database = $databases->where('uuid', $uuid)->first(); - if ($database) { - $isPublic = data_get($database, 'is_public'); - $foundDatabases[] = $database->id; - $statusFromDb = $database->status; - if ($statusFromDb !== $containerStatus) { - $database->update(['status' => $containerStatus]); - } - if ($isPublic) { - $foundTcpProxy = $containers->filter(function ($value, $key) use ($uuid) { - if ($this->server->isSwarm()) { - return data_get($value, 'Spec.Name') === "coolify-proxy_$uuid"; - } else { - return data_get($value, 'Name') === "/$uuid-proxy"; + if ($type === 'service') { + $database_id = data_get($labels, 'coolify.service.subId'); + if ($database_id) { + $service_db = ServiceDatabase::where('id', $database_id)->first(); + if ($service_db) { + $uuid = $service_db->service->uuid; + $isPublic = data_get($service_db, 'is_public'); + if ($isPublic) { + $foundTcpProxy = $containers->filter(function ($value, $key) use ($uuid) { + if ($this->server->isSwarm()) { + return data_get($value, 'Spec.Name') === "coolify-proxy_$uuid"; + } else { + return data_get($value, 'Name') === "/$uuid-proxy"; + } + })->first(); + if (!$foundTcpProxy) { + StartDatabaseProxy::run($service_db); + $this->server->team?->notify(new ContainerRestarted("TCP Proxy for {$service_db->service->name}", $this->server)); + } } - })->first(); - if (!$foundTcpProxy) { - StartDatabaseProxy::run($database); - $this->server->team?->notify(new ContainerRestarted("TCP Proxy for {$database->name}", $this->server)); } } } else { - // Notify user that this container should not be there. + $database = $databases->where('uuid', $uuid)->first(); + if ($uuid == 'postgresql') { + ray($database); + } + if ($database) { + $isPublic = data_get($database, 'is_public'); + $foundDatabases[] = $database->id; + $statusFromDb = $database->status; + if ($statusFromDb !== $containerStatus) { + $database->update(['status' => $containerStatus]); + } + ray($database); + if ($isPublic) { + $foundTcpProxy = $containers->filter(function ($value, $key) use ($uuid) { + if ($this->server->isSwarm()) { + return data_get($value, 'Spec.Name') === "coolify-proxy_$uuid"; + } else { + return data_get($value, 'Name') === "/$uuid-proxy"; + } + })->first(); + if (!$foundTcpProxy) { + ray('asdffff'); + StartDatabaseProxy::run($database); + $this->server->team?->notify(new ContainerRestarted("TCP Proxy for {$database->name}", $this->server)); + } + } + } else { + // Notify user that this container should not be there. + } } + } if (data_get($container, 'Name') === '/coolify-db') { $foundDatabases[] = 0; diff --git a/app/Livewire/ActivityMonitor.php b/app/Livewire/ActivityMonitor.php index ad2a599a1..421992cb5 100644 --- a/app/Livewire/ActivityMonitor.php +++ b/app/Livewire/ActivityMonitor.php @@ -13,6 +13,7 @@ class ActivityMonitor extends Component public $activityId; public $eventToDispatch = 'activityFinished'; public $isPollingActive = false; + public bool $showWaiting = false; protected $activity; protected $listeners = ['activityMonitor' => 'newMonitorActivity']; diff --git a/app/Livewire/Boarding/Index.php b/app/Livewire/Boarding/Index.php index c77aa54ec..110222fb4 100644 --- a/app/Livewire/Boarding/Index.php +++ b/app/Livewire/Boarding/Index.php @@ -2,22 +2,27 @@ namespace App\Livewire\Boarding; -use App\Actions\Server\InstallDocker; use App\Enums\ProxyTypes; use App\Models\PrivateKey; use App\Models\Project; use App\Models\Server; use App\Models\Team; use Illuminate\Support\Collection; +use Livewire\Attributes\Url; use Livewire\Component; class Index extends Component { protected $listeners = ['serverInstalled' => 'validateServer']; - public string $currentState = 'welcome'; + #[Url()] + public string $state = 'welcome'; + + #[Url()] public ?string $selectedServerType = null; public ?Collection $privateKeys = null; + + #[Url()] public ?int $selectedExistingPrivateKey = null; public ?string $privateKeyType = null; public ?string $privateKey = null; @@ -27,6 +32,8 @@ class Index extends Component public ?PrivateKey $createdPrivateKey = null; public ?Collection $servers = null; + + #[Url()] public ?int $selectedExistingServer = null; public ?string $remoteServerName = null; public ?string $remoteServerDescription = null; @@ -38,7 +45,9 @@ class Index extends Component public ?Server $createdServer = null; public Collection $projects; - public ?int $selectedExistingProject = null; + + #[Url()] + public ?int $selectedProject = null; public ?Project $createdProject = null; public bool $dockerInstallationStarted = false; @@ -62,13 +71,33 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== $this->remoteServerDescription = 'Created by Coolify'; $this->remoteServerHost = 'coolify-testing-host'; } + if ($this->state === 'create-project') { + $this->getProjects(); + } + if ($this->state === 'create-resource') { + $this->selectExistingServer(); + $this->selectExistingProject(); + } + if ($this->state === 'private-key') { + $this->setServerType('remote'); + } + if ($this->state === 'create-server') { + $this->selectExistingPrivateKey(); + } + if ($this->state === 'validate-server') { + $this->selectExistingServer(); + } + if ($this->state === 'select-existing-server') { + $this->selectExistingServer(); + } + } public function explanation() { if (isCloud()) { return $this->setServerType('remote'); } - $this->currentState = 'select-server-type'; + $this->state = 'select-server-type'; } public function restartBoarding() @@ -89,6 +118,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== $this->selectedServerType = $type; if ($this->selectedServerType === 'localhost') { $this->createdServer = Server::find(0); + $this->selectedExistingServer = 0; if (!$this->createdServer) { return $this->dispatch('error', 'Localhost server is not found. Something went wrong during installation. Please try to reinstall or contact support.'); } @@ -106,10 +136,10 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== $this->servers = Server::ownedByCurrentTeam(['name'])->where('id', '!=', 0)->get(); if ($this->servers->count() > 0) { $this->selectedExistingServer = $this->servers->first()->id; - $this->currentState = 'select-existing-server'; + $this->state = 'select-existing-server'; return; } - $this->currentState = 'private-key'; + $this->state = 'private-key'; } } public function selectExistingServer() @@ -117,12 +147,12 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== $this->createdServer = Server::find($this->selectedExistingServer); if (!$this->createdServer) { $this->dispatch('error', 'Server is not found.'); - $this->currentState = 'private-key'; + $this->state = 'private-key'; return; } $this->selectedExistingPrivateKey = $this->createdServer->privateKey->id; $this->serverPublicKey = $this->createdServer->privateKey->publicKey(); - $this->currentState = 'validate-server'; + $this->state = 'validate-server'; } public function getProxyType() { @@ -130,21 +160,25 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== $this->selectProxy(ProxyTypes::TRAEFIK_V2->value); // $proxyTypeSet = $this->createdServer->proxy->type; // if (!$proxyTypeSet) { - // $this->currentState = 'select-proxy'; + // $this->state = 'select-proxy'; // return; // } $this->getProjects(); } public function selectExistingPrivateKey() { + if (is_null($this->selectedExistingPrivateKey)) { + $this->restartBoarding(); + return; + } $this->createdPrivateKey = PrivateKey::find($this->selectedExistingPrivateKey); $this->privateKey = $this->createdPrivateKey->private_key; - $this->currentState = 'create-server'; + $this->state = 'create-server'; } public function createNewServer() { $this->selectedExistingServer = null; - $this->currentState = 'private-key'; + $this->state = 'private-key'; } public function setPrivateKey(string $type) { @@ -153,7 +187,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== if ($type === 'create') { $this->createNewPrivateKey(); } - $this->currentState = 'create-private-key'; + $this->state = 'create-private-key'; } public function savePrivateKey() { @@ -168,7 +202,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== 'team_id' => currentTeam()->id ]); $this->createdPrivateKey->save(); - $this->currentState = 'create-server'; + $this->state = 'create-server'; } public function saveServer() { @@ -196,7 +230,8 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== $this->createdServer->settings->is_cloudflare_tunnel = $this->isCloudflareTunnel; $this->createdServer->settings->save(); $this->createdServer->addInitialNetwork(); - $this->currentState = 'validate-server'; + $this->selectedExistingServer = $this->createdServer->id; + $this->state = 'validate-server'; } public function installServer() { @@ -223,7 +258,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== $dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $this->createdServer, true); $dockerVersion = checkMinimumDockerEngineVersion($dockerVersion); if (is_null($dockerVersion)) { - $this->currentState = 'validate-server'; + $this->state = 'validate-server'; throw new \Exception('Docker not found or old version is installed.'); } $this->createdServer->settings()->update([ @@ -249,14 +284,14 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== { $this->projects = Project::ownedByCurrentTeam(['name'])->get(); if ($this->projects->count() > 0) { - $this->selectedExistingProject = $this->projects->first()->id; + $this->selectedProject = $this->projects->first()->id; } - $this->currentState = 'create-project'; + $this->state = 'create-project'; } public function selectExistingProject() { - $this->createdProject = Project::find($this->selectedExistingProject); - $this->currentState = 'create-resource'; + $this->createdProject = Project::find($this->selectedProject); + $this->state = 'create-resource'; } public function createNewProject() { @@ -264,7 +299,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== 'name' => "My first project", 'team_id' => currentTeam()->id ]); - $this->currentState = 'create-resource'; + $this->state = 'create-resource'; } public function showNewResource() { diff --git a/app/Livewire/Dashboard.php b/app/Livewire/Dashboard.php index 632f14d65..8a5d491e4 100644 --- a/app/Livewire/Dashboard.php +++ b/app/Livewire/Dashboard.php @@ -3,6 +3,7 @@ namespace App\Livewire; use App\Models\ApplicationDeploymentQueue; +use App\Models\PrivateKey; use App\Models\Project; use App\Models\Server; use Illuminate\Support\Collection; @@ -13,9 +14,11 @@ class Dashboard extends Component { public $projects = []; public Collection $servers; + public Collection $private_keys; public $deployments_per_server; public function mount() { + $this->private_keys = PrivateKey::ownedByCurrentTeam()->get(); $this->servers = Server::ownedByCurrentTeam()->get(); $this->projects = Project::ownedByCurrentTeam()->get(); $this->get_deployments(); diff --git a/app/Livewire/Destination/New/Docker.php b/app/Livewire/Destination/New/Docker.php index 66d0df82e..d87f4bc0a 100644 --- a/app/Livewire/Destination/New/Docker.php +++ b/app/Livewire/Destination/New/Docker.php @@ -5,7 +5,7 @@ namespace App\Livewire\Destination\New; use App\Models\Server; use App\Models\StandaloneDocker as ModelsStandaloneDocker; use App\Models\SwarmDocker; -use Illuminate\Database\Eloquent\Collection; +use Illuminate\Support\Collection; use Livewire\Component; use Visus\Cuid2\Cuid2; @@ -14,7 +14,7 @@ class Docker extends Component public string $name; public string $network; - public Collection $servers; + public ?Collection $servers = null; public Server $server; public ?int $server_id = null; public bool $is_swarm = false; @@ -34,6 +34,9 @@ class Docker extends Component public function mount() { + if (is_null($this->servers)) { + $this->servers = Server::isReachable()->get(); + } if (request()->query('server_id')) { $this->server_id = request()->query('server_id'); } else { @@ -46,7 +49,9 @@ class Docker extends Component } else { $this->network = new Cuid2(7); } - $this->name = str("{$this->servers->first()->name}-{$this->network}")->kebab(); + if ($this->servers->count() > 0) { + $this->name = str("{$this->servers->first()->name}-{$this->network}")->kebab(); + } } public function generate_name() diff --git a/app/Livewire/Destination/Show.php b/app/Livewire/Destination/Show.php index b9cbcc147..4bdbf88b0 100644 --- a/app/Livewire/Destination/Show.php +++ b/app/Livewire/Destination/Show.php @@ -3,6 +3,8 @@ namespace App\Livewire\Destination; use App\Models\Server; +use App\Models\StandaloneDocker; +use App\Models\SwarmDocker; use Illuminate\Support\Collection; use Livewire\Component; @@ -11,6 +13,40 @@ class Show extends Component public Server $server; public Collection|array $networks = []; + private function createNetworkAndAttachToProxy() + { + $connectProxyToDockerNetworks = connectProxyToNetworks($this->server); + instant_remote_process($connectProxyToDockerNetworks, $this->server, false); + } + public function add($name) + { + if ($this->server->isSwarm()) { + $found = $this->server->swarmDockers()->where('network', $name)->first(); + if ($found) { + $this->dispatch('error', 'Network already added to this server.'); + return; + } else { + SwarmDocker::create([ + 'name' => $this->server->name . "-" . $name, + 'network' => $this->name, + 'server_id' => $this->server->id, + ]); + } + } else { + $found = $this->server->standaloneDockers()->where('network', $name)->first(); + if ($found) { + $this->dispatch('error', 'Network already added to this server.'); + return; + } else { + StandaloneDocker::create([ + 'name' => $this->server->name . "-" . $name, + 'network' => $name, + 'server_id' => $this->server->id, + ]); + } + $this->createNetworkAndAttachToProxy(); + } + } public function scan() { if ($this->server->isSwarm()) { @@ -26,6 +62,8 @@ class Show extends Component }); if ($this->networks->count() === 0) { $this->dispatch('success', 'No new networks found.'); + return; } + $this->dispatch('success', 'Scan done.'); } } diff --git a/app/Livewire/LayoutPopups.php b/app/Livewire/LayoutPopups.php index b6f06f808..136c94ca2 100644 --- a/app/Livewire/LayoutPopups.php +++ b/app/Livewire/LayoutPopups.php @@ -17,14 +17,6 @@ class LayoutPopups extends Component { $this->dispatch('success', 'Realtime events configured!'); } - public function disableSponsorship() - { - auth()->user()->update(['is_notification_sponsorship_enabled' => false]); - } - public function disableNotifications() - { - auth()->user()->update(['is_notification_notifications_enabled' => false]); - } public function render() { return view('livewire.layout-popups'); diff --git a/app/Livewire/Notifications/DiscordSettings.php b/app/Livewire/Notifications/Discord.php similarity index 91% rename from app/Livewire/Notifications/DiscordSettings.php rename to app/Livewire/Notifications/Discord.php index f5f0d5591..8aad8ccf0 100644 --- a/app/Livewire/Notifications/DiscordSettings.php +++ b/app/Livewire/Notifications/Discord.php @@ -6,7 +6,7 @@ use App\Models\Team; use App\Notifications\Test; use Livewire\Component; -class DiscordSettings extends Component +class Discord extends Component { public Team $team; protected $rules = [ @@ -55,4 +55,8 @@ class DiscordSettings extends Component $this->team?->notify(new Test()); $this->dispatch('success', 'Test notification sent.'); } + public function render() + { + return view('livewire.notifications.discord'); + } } diff --git a/app/Livewire/Notifications/EmailSettings.php b/app/Livewire/Notifications/Email.php similarity index 89% rename from app/Livewire/Notifications/EmailSettings.php rename to app/Livewire/Notifications/Email.php index b6152907d..343cbda3e 100644 --- a/app/Livewire/Notifications/EmailSettings.php +++ b/app/Livewire/Notifications/Email.php @@ -2,13 +2,12 @@ namespace App\Livewire\Notifications; +use Livewire\Component; use App\Models\InstanceSettings; use App\Models\Team; use App\Notifications\Test; -use Livewire\Component; -use Log; -class EmailSettings extends Component +class Email extends Component { public Team $team; public string $emails; @@ -119,16 +118,18 @@ class EmailSettings extends Component { try { $this->resetErrorBag(); - $this->validate([ - 'team.smtp_from_address' => 'required|email', - 'team.smtp_from_name' => 'required', - 'team.smtp_host' => 'required', - 'team.smtp_port' => 'required|numeric', - 'team.smtp_encryption' => 'nullable', - 'team.smtp_username' => 'nullable', - 'team.smtp_password' => 'nullable', - 'team.smtp_timeout' => 'nullable', - ]); + if (!$this->team->use_instance_email_settings) { + $this->validate([ + 'team.smtp_from_address' => 'required|email', + 'team.smtp_from_name' => 'required', + 'team.smtp_host' => 'required', + 'team.smtp_port' => 'required|numeric', + 'team.smtp_encryption' => 'nullable', + 'team.smtp_username' => 'nullable', + 'team.smtp_password' => 'nullable', + 'team.smtp_timeout' => 'nullable', + ]); + } $this->team->save(); refreshSession(); $this->dispatch('success', 'Settings saved.'); @@ -189,4 +190,8 @@ class EmailSettings extends Component } $this->dispatch('error', 'Instance SMTP/Resend settings are not enabled.'); } + public function render() + { + return view('livewire.notifications.email'); + } } diff --git a/app/Livewire/Notifications/TelegramSettings.php b/app/Livewire/Notifications/Telegram.php similarity index 93% rename from app/Livewire/Notifications/TelegramSettings.php rename to app/Livewire/Notifications/Telegram.php index 0f581a515..35b868527 100644 --- a/app/Livewire/Notifications/TelegramSettings.php +++ b/app/Livewire/Notifications/Telegram.php @@ -6,8 +6,9 @@ use App\Models\Team; use App\Notifications\Test; use Livewire\Component; -class TelegramSettings extends Component +class Telegram extends Component { + public Team $team; protected $rules = [ 'team.telegram_enabled' => 'nullable|boolean', @@ -61,4 +62,8 @@ class TelegramSettings extends Component $this->team?->notify(new Test()); $this->dispatch('success', 'Test notification sent.'); } + public function render() + { + return view('livewire.notifications.telegram'); + } } diff --git a/app/Livewire/Profile/Index.php b/app/Livewire/Profile/Index.php index abfc0b972..631d4f956 100644 --- a/app/Livewire/Profile/Index.php +++ b/app/Livewire/Profile/Index.php @@ -11,11 +11,8 @@ class Index extends Component public int $userId; public string $email; - #[Validate('required')] public string $current_password; - #[Validate('required|min:8')] public string $new_password; - #[Validate('required|min:8|same:new_password')] public string $new_password_confirmation; #[Validate('required')] @@ -29,7 +26,9 @@ class Index extends Component public function submit() { try { - $this->validate(); + $this->validate([ + 'name' => 'required', + ]); auth()->user()->update([ 'name' => $this->name, ]); @@ -42,7 +41,11 @@ class Index extends Component public function resetPassword() { try { - $this->validate(); + $this->validate([ + 'current_password' => 'required', + 'new_password' => 'required|min:8', + 'new_password_confirmation' => 'required|min:8|same:new_password', + ]); if (!Hash::check($this->current_password, auth()->user()->password)) { $this->dispatch('error', 'Current password is incorrect.'); return; diff --git a/app/Livewire/Project/Application/Deployment/Index.php b/app/Livewire/Project/Application/Deployment/Index.php index 520848a54..d8e033b24 100644 --- a/app/Livewire/Project/Application/Deployment/Index.php +++ b/app/Livewire/Project/Application/Deployment/Index.php @@ -9,7 +9,7 @@ use Livewire\Component; class Index extends Component { public Application $application; - public array|Collection $deployments = []; + public ?Collection $deployments; public int $deployments_count = 0; public string $current_url; public int $skip = 0; @@ -48,9 +48,9 @@ class Index extends Component } private function show_more() { - if (count($this->deployments) !== 0) { + if ($this->deployments->count() !== 0) { $this->show_next = true; - if (count($this->deployments) < $this->default_take) { + if ($this->deployments->count() < $this->default_take) { $this->show_next = false; } return; @@ -63,7 +63,6 @@ class Index extends Component } public function previous_page(?int $take = null) { - if ($take) { $this->skip = $this->skip - $take; } diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index e530a0698..67f6c2115 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -251,7 +251,7 @@ class General extends Component if ($this->application->additional_servers->count() === 0) { foreach ($domains as $domain) { if (!validate_dns_entry($domain, $this->application->destination->server)) { - $showToaster && $this->dispatch('error', "Validating DNS ($domain) failed.", "Make sure you have added the DNS records correctly.

Check this documentation for further help."); + $showToaster && $this->dispatch('error', "Validating DNS ($domain) failed.", "Make sure you have added the DNS records correctly.

Check this documentation for further help."); } } } diff --git a/app/Livewire/Project/Database/BackupEdit.php b/app/Livewire/Project/Database/BackupEdit.php index 86aec0f6a..f5f476257 100644 --- a/app/Livewire/Project/Database/BackupEdit.php +++ b/app/Livewire/Project/Database/BackupEdit.php @@ -42,19 +42,21 @@ class BackupEdit extends Component public function delete() { - // TODO: Delete backup from server and add a confirmation modal - $this->backup->delete(); - if ($this->backup->database->getMorphClass() === 'App\Models\ServiceDatabase') { - $previousUrl = url()->previous(); - $url = Url::fromString($previousUrl); - $url = $url->withoutQueryParameter('selectedBackupId'); - $url = $url->withFragment('backups'); - $url = $url->getPath() . "#{$url->getFragment()}"; - return redirect($url); - } else { - return redirect()->route('project.database.backup.index', $this->parameters); + try { + $this->backup->delete(); + if ($this->backup->database->getMorphClass() === 'App\Models\ServiceDatabase') { + $previousUrl = url()->previous(); + $url = Url::fromString($previousUrl); + $url = $url->withoutQueryParameter('selectedBackupId'); + $url = $url->withFragment('backups'); + $url = $url->getPath() . "#{$url->getFragment()}"; + return redirect($url); + } else { + return redirect()->route('project.database.backup.index', $this->parameters); + } + } catch (\Throwable $e) { + return handleError($e, $this); } - } public function instantSave() @@ -63,7 +65,7 @@ class BackupEdit extends Component $this->custom_validate(); $this->backup->save(); $this->backup->refresh(); - $this->dispatch('success', 'Backup updated successfully'); + $this->dispatch('success', 'Backup updated successfully.'); } catch (\Throwable $e) { $this->dispatch('error', $e->getMessage()); } diff --git a/app/Livewire/Project/Edit.php b/app/Livewire/Project/Edit.php index a80b1af76..17cb6902b 100644 --- a/app/Livewire/Project/Edit.php +++ b/app/Livewire/Project/Edit.php @@ -46,10 +46,11 @@ class Edit extends Component public function submit() { - $this->validate(); try { + $this->validate(); $this->project->save(); $this->dispatch('saved'); + $this->dispatch('success', 'Project updated.'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Livewire/Project/Index.php b/app/Livewire/Project/Index.php index 1e6f79855..0537ad192 100644 --- a/app/Livewire/Project/Index.php +++ b/app/Livewire/Project/Index.php @@ -2,6 +2,7 @@ namespace App\Livewire\Project; +use App\Models\PrivateKey; use App\Models\Project; use App\Models\Server; use Livewire\Component; @@ -10,7 +11,9 @@ class Index extends Component { public $projects; public $servers; + public $private_keys; public function mount() { + $this->private_keys = PrivateKey::ownedByCurrentTeam()->get(); $this->projects = Project::ownedByCurrentTeam()->get(); $this->servers = Server::ownedByCurrentTeam()->count(); } diff --git a/app/Livewire/Project/New/Select.php b/app/Livewire/Project/New/Select.php index 8178590a3..00a243624 100644 --- a/app/Livewire/Project/New/Select.php +++ b/app/Livewire/Project/New/Select.php @@ -90,8 +90,7 @@ class Select extends Component $this->allServices = getServiceTemplates(); $this->services = $this->allServices->filter(function ($service, $key) { return str_contains(strtolower($key), strtolower($this->search)); - });; - $this->dispatch('success', 'Successfully loaded services.'); + }); } } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Livewire/Project/Service/Configuration.php b/app/Livewire/Project/Service/Configuration.php index eb72c803c..cdedb3f8e 100644 --- a/app/Livewire/Project/Service/Configuration.php +++ b/app/Livewire/Project/Service/Configuration.php @@ -36,6 +36,30 @@ class Configuration extends Component $this->applications = $this->service->applications->sort(); $this->databases = $this->service->databases->sort(); } + public function restartApplication($id) + { + try { + $application = $this->service->applications->find($id); + if ($application) { + $application->restart(); + $this->dispatch('success', 'Application restarted successfully.'); + } + } catch (\Exception $e) { + return handleError($e, $this); + } + } + public function restartDatabase($id) + { + try { + $database = $this->service->databases->find($id); + if ($database) { + $database->restart(); + $this->dispatch('success', 'Database restarted successfully.'); + } + } catch (\Exception $e) { + return handleError($e, $this); + } + } public function check_status() { try { diff --git a/app/Livewire/Project/Service/Database.php b/app/Livewire/Project/Service/Database.php index 8dec97852..d7c1c9f5c 100644 --- a/app/Livewire/Project/Service/Database.php +++ b/app/Livewire/Project/Service/Database.php @@ -34,7 +34,11 @@ class Database extends Component } $this->refreshFileStorages(); } - public function instantSaveAdvanced() + public function instantSaveExclude() + { + $this->submit(); + } + public function instantSaveLogDrain() { if (!$this->database->service->destination->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; diff --git a/app/Livewire/Modal/EditCompose.php b/app/Livewire/Project/Service/EditCompose.php similarity index 69% rename from app/Livewire/Modal/EditCompose.php rename to app/Livewire/Project/Service/EditCompose.php index f2804e5ac..cc385315e 100644 --- a/app/Livewire/Modal/EditCompose.php +++ b/app/Livewire/Project/Service/EditCompose.php @@ -1,11 +1,11 @@ service = Service::find($this->serviceId); } - public function render() - { - return view('livewire.modal.edit-compose'); - } - public function submit() { + + public function saveEditedCompose() { $this->dispatch('warning', "Saving new docker compose..."); $this->dispatch('saveCompose', $this->service->docker_compose_raw); - $this->closeModal(); + } + public function render() + { + return view('livewire.project.service.edit-compose'); } } diff --git a/app/Livewire/Project/Service/Modal.php b/app/Livewire/Project/Service/Modal.php deleted file mode 100644 index 653425835..000000000 --- a/app/Livewire/Project/Service/Modal.php +++ /dev/null @@ -1,13 +0,0 @@ -user()->id; return [ + "echo-private:user.{$userId},ServiceStatusChanged" => 'serviceStarted', "serviceStatusChanged" ]; } + public function serviceStarted() { + $this->dispatch('success', 'Service status changed.'); + } public function serviceStatusChanged() { $this->dispatch('refresh')->self(); } - public function check_status() { + public function check_status() + { $this->dispatch('check_status'); $this->dispatch('success', 'Service status updated.'); } @@ -44,7 +51,7 @@ class Navbar extends Component $this->isDeploymentProgress = false; } } - public function deploy() + public function start() { $this->checkDeployments(); if ($this->isDeploymentProgress) { @@ -73,9 +80,9 @@ class Navbar extends Component return; } PullImage::run($this->service); - $this->dispatch('image-pulled'); StopService::run($this->service); $this->service->parse(); + $this->dispatch('imagePulled'); $activity = StartService::run($this->service); $this->dispatch('activityMonitor', $activity->id); } diff --git a/app/Livewire/Project/Service/ServiceApplicationView.php b/app/Livewire/Project/Service/ServiceApplicationView.php index 29bd796fd..0b3a4cef6 100644 --- a/app/Livewire/Project/Service/ServiceApplicationView.php +++ b/app/Livewire/Project/Service/ServiceApplicationView.php @@ -59,7 +59,7 @@ class ServiceApplicationView extends Component $this->validate(); $this->application->save(); updateCompose($this->application); - $this->dispatch('success', 'Application saved.'); + $this->dispatch('success', 'Service saved.'); } catch (\Throwable $e) { return handleError($e, $this); } finally { diff --git a/app/Livewire/Project/Service/StackForm.php b/app/Livewire/Project/Service/StackForm.php index 650dde792..1bfb70c5e 100644 --- a/app/Livewire/Project/Service/StackForm.php +++ b/app/Livewire/Project/Service/StackForm.php @@ -2,11 +2,12 @@ namespace App\Livewire\Project\Service; +use App\Models\Service; use Livewire\Component; class StackForm extends Component { - public $service; + public Service $service; public $fields = []; protected $listeners = ["saveCompose"]; public $rules = [ diff --git a/app/Livewire/Project/Shared/ScheduledTask/Add.php b/app/Livewire/Project/Shared/ScheduledTask/Add.php index 3cc5428b8..3a7a3fa23 100644 --- a/app/Livewire/Project/Shared/ScheduledTask/Add.php +++ b/app/Livewire/Project/Shared/ScheduledTask/Add.php @@ -33,19 +33,23 @@ class Add extends Component public function submit() { - $this->validate(); - $isValid = validate_cron_expression($this->frequency); - if (!$isValid) { - $this->dispatch('error', 'Invalid Cron / Human expression.'); - return; + try { + $this->validate(); + $isValid = validate_cron_expression($this->frequency); + if (!$isValid) { + $this->dispatch('error', 'Invalid Cron / Human expression.'); + return; + } + $this->dispatch('saveScheduledTask', [ + 'name' => $this->name, + 'command' => $this->command, + 'frequency' => $this->frequency, + 'container' => $this->container, + ]); + $this->clear(); + } catch (\Exception $e) { + return handleError($e, $this); } - $this->dispatch('saveScheduledTask', [ - 'name' => $this->name, - 'command' => $this->command, - 'frequency' => $this->frequency, - 'container' => $this->container, - ]); - $this->clear(); } public function clear() diff --git a/app/Livewire/Project/Shared/Tags.php b/app/Livewire/Project/Shared/Tags.php index 0977f18f8..92a08f117 100644 --- a/app/Livewire/Project/Shared/Tags.php +++ b/app/Livewire/Project/Shared/Tags.php @@ -28,7 +28,7 @@ class Tags extends Component { try { if ($this->resource->tags()->where('id', $id)->exists()) { - $this->dispatch('error', 'Duplicate tags.', "Tag $name already added."); + $this->dispatch('error', 'Duplicate tags.', "Tag $name already added."); return; } $this->resource->tags()->syncWithoutDetaching($id); @@ -66,7 +66,7 @@ class Tags extends Component $tags = str($this->new_tag)->trim()->explode(' '); foreach ($tags as $tag) { if ($this->resource->tags()->where('name', $tag)->exists()) { - $this->dispatch('error', 'Duplicate tags.', "Tag $tag already added."); + $this->dispatch('error', 'Duplicate tags.', "Tag $tag already added."); continue; } $found = Tag::where(['name' => $tag, 'team_id' => currentTeam()->id])->first(); diff --git a/app/Livewire/Security/PrivateKey/Create.php b/app/Livewire/Security/PrivateKey/Create.php index 62d763601..cd1c06568 100644 --- a/app/Livewire/Security/PrivateKey/Create.php +++ b/app/Livewire/Security/PrivateKey/Create.php @@ -67,7 +67,7 @@ class Create extends Component 'team_id' => currentTeam()->id ]); if ($this->from === 'server') { - return redirect()->route('server.create'); + return redirect()->route('dashboard'); } return redirect()->route('security.private-key.show', ['private_key_uuid' => $private_key->uuid]); } catch (\Throwable $e) { diff --git a/app/Livewire/Security/PrivateKey/Show.php b/app/Livewire/Security/PrivateKey/Show.php index a4fbaef52..0540b2e29 100644 --- a/app/Livewire/Security/PrivateKey/Show.php +++ b/app/Livewire/Security/PrivateKey/Show.php @@ -50,6 +50,7 @@ class Show extends Component $this->private_key->private_key = formatPrivateKey($this->private_key->private_key); $this->private_key->save(); refresh_server_connection($this->private_key); + $this->dispatch('success', 'Private key updated.'); } catch (\Throwable $e) { return handleError($e, $this); } diff --git a/app/Livewire/Server/New/ByIp.php b/app/Livewire/Server/New/ByIp.php index df3fae20f..1ce3df273 100644 --- a/app/Livewire/Server/New/ByIp.php +++ b/app/Livewire/Server/New/ByIp.php @@ -53,7 +53,7 @@ class ByIp extends Component public function mount() { $this->name = generate_random_name(); - $this->private_key_id = $this->private_keys->first()->id; + $this->private_key_id = $this->private_keys->first()?->id; $this->swarm_managers = Server::isUsable()->get()->where('settings.is_swarm_manager', true); if ($this->swarm_managers->count() > 0) { $this->selected_swarm_cluster = $this->swarm_managers->first()->id; diff --git a/app/Livewire/Server/Proxy/Deploy.php b/app/Livewire/Server/Proxy/Deploy.php index 72d0b3884..8a029e6a1 100644 --- a/app/Livewire/Server/Proxy/Deploy.php +++ b/app/Livewire/Server/Proxy/Deploy.php @@ -49,7 +49,8 @@ class Deploy extends Component { $this->server->refresh(); } - public function restart() { + public function restart() + { try { $this->stop(); $this->dispatch('checkProxy'); diff --git a/app/Livewire/Settings/Auth.php b/app/Livewire/Settings/Auth.php new file mode 100644 index 000000000..100f99a73 --- /dev/null +++ b/app/Livewire/Settings/Auth.php @@ -0,0 +1,43 @@ +reduce(function($carry, $setting) { + $carry["oauth_settings_map.$setting->provider.enabled"] = 'required'; + $carry["oauth_settings_map.$setting->provider.client_id"] = 'nullable'; + $carry["oauth_settings_map.$setting->provider.client_secret"] = 'nullable'; + $carry["oauth_settings_map.$setting->provider.redirect_uri"] = 'nullable'; + $carry["oauth_settings_map.$setting->provider.tenant"] = 'nullable'; + return $carry; + }, []); + } + + public function mount() { + $this->oauth_settings_map = OauthSetting::all()->sortBy('provider')->reduce(function($carry, $setting) { + $carry[$setting->provider] = $setting; + return $carry; + }, []); + } + + private function updateOauthSettings() { + foreach (array_values($this->oauth_settings_map) as &$setting) { + $setting->save(); + } + } + + public function instantSave() { + $this->updateOauthSettings(); + } + + public function submit() { + $this->updateOauthSettings(); + $this->dispatch('success', 'Instance settings updated successfully!'); + } +} diff --git a/app/Livewire/Settings/License.php b/app/Livewire/Settings/License.php index 64ad0a6f7..e2ae5fcf7 100644 --- a/app/Livewire/Settings/License.php +++ b/app/Livewire/Settings/License.php @@ -30,7 +30,7 @@ class License extends Component } public function render() { - return view('livewire.settings.license')->layout('layouts.subscription'); + return view('livewire.settings.license'); } public function submit() { diff --git a/app/Livewire/Subscription/Index.php b/app/Livewire/Subscription/Index.php index 4f36750c7..c87f7d0b6 100644 --- a/app/Livewire/Subscription/Index.php +++ b/app/Livewire/Subscription/Index.php @@ -31,6 +31,6 @@ class Index extends Component } public function render() { - return view('livewire.subscription.index')->layout('layouts.subscription'); + return view('livewire.subscription.index'); } } diff --git a/app/Livewire/SwitchTeam.php b/app/Livewire/SwitchTeam.php index 845619820..49b73cdc6 100644 --- a/app/Livewire/SwitchTeam.php +++ b/app/Livewire/SwitchTeam.php @@ -8,7 +8,9 @@ use Livewire\Component; class SwitchTeam extends Component { public string $selectedTeamId = 'default'; - + public function mount() { + $this->selectedTeamId = auth()->user()->currentTeam()->id; + } public function updatedSelectedTeamId() { $this->switch_to($this->selectedTeamId); diff --git a/app/Livewire/Tags/Index.php b/app/Livewire/Tags/Index.php index eba25a750..75ed06f7b 100644 --- a/app/Livewire/Tags/Index.php +++ b/app/Livewire/Tags/Index.php @@ -2,14 +2,73 @@ namespace App\Livewire\Tags; +use App\Http\Controllers\Api\Deploy; +use App\Models\ApplicationDeploymentQueue; use App\Models\Tag; +use Illuminate\Support\Collection; +use Livewire\Attributes\Url; use Livewire\Component; class Index extends Component { - public $tags = []; - public function mount() { - $this->tags = Tag::where('team_id', currentTeam()->id)->get()->unique('name')->sortBy('name'); + #[Url()] + public ?string $tag = null; + + public Collection $tags; + public Collection $applications; + public Collection $services; + public $webhook = null; + public $deployments_per_tag_per_server = []; + + public function updatedTag() + { + $tag = $this->tags->where('name', $this->tag)->first(); + $this->webhook = generatTagDeployWebhook($tag->name); + $this->applications = $tag->applications()->get(); + $this->services = $tag->services()->get(); + $this->get_deployments(); + } + public function get_deployments() + { + try { + $resource_ids = $this->applications->pluck('id'); + $this->deployments_per_tag_per_server = ApplicationDeploymentQueue::whereIn("status", ["in_progress", "queued"])->whereIn('application_id', $resource_ids)->get([ + "id", + "application_id", + "application_name", + "deployment_url", + "pull_request_id", + "server_name", + "server_id", + "status" + ])->sortBy('id')->groupBy('server_name')->toArray(); + } catch (\Exception $e) { + return handleError($e, $this); + } + } + public function redeploy_all() + { + try { + $message = collect([]); + $this->applications->each(function ($resource) use ($message) { + $deploy = new Deploy(); + $message->push($deploy->deploy_resource($resource)); + }); + $this->services->each(function ($resource) use ($message) { + $deploy = new Deploy(); + $message->push($deploy->deploy_resource($resource)); + }); + $this->dispatch('success', 'Mass deployment started.'); + } catch (\Exception $e) { + return handleError($e, $this); + } + } + public function mount() + { + $this->tags = Tag::ownedByCurrentTeam()->get()->unique('name')->sortBy('name'); + if ($this->tag) { + $this->updatedTag(); + } } public function render() { diff --git a/app/Livewire/Team/Notification/Index.php b/app/Livewire/Team/Notification/Index.php deleted file mode 100644 index 86754d619..000000000 --- a/app/Livewire/Team/Notification/Index.php +++ /dev/null @@ -1,13 +0,0 @@ - empty($value) ? null : Crypt::decryptString($value), + set: fn (string | null $value) => empty($value) ? null : Crypt::encryptString($value), + ); + } +} diff --git a/app/Models/ServiceApplication.php b/app/Models/ServiceApplication.php index 37f7d9c9c..820ef6fee 100644 --- a/app/Models/ServiceApplication.php +++ b/app/Models/ServiceApplication.php @@ -19,6 +19,11 @@ class ServiceApplication extends BaseModel $service->fileStorages()->delete(); }); } + public function restart() + { + $container_id = $this->name . '-' . $this->service->uuid; + instant_remote_process(["docker restart {$container_id}"], $this->service->server); + } public function isLogDrainEnabled() { return data_get($this, 'is_log_drain_enabled', false); diff --git a/app/Models/ServiceDatabase.php b/app/Models/ServiceDatabase.php index 9375fe807..76c174d08 100644 --- a/app/Models/ServiceDatabase.php +++ b/app/Models/ServiceDatabase.php @@ -17,6 +17,11 @@ class ServiceDatabase extends BaseModel $service->fileStorages()->delete(); }); } + public function restart() + { + $container_id = $this->name . '-' . $this->service->uuid; + remote_process(["docker restart {$container_id}"], $this->service->server); + } public function isLogDrainEnabled() { return data_get($this, 'is_log_drain_enabled', false); @@ -52,8 +57,7 @@ class ServiceDatabase extends BaseModel if ($this->service->server->isLocalhost() || isDev()) { $realIp = base_ip(); } - $url = "{$realIp}:{$port}"; - return $url; + return "{$realIp}:{$port}"; } public function service() { diff --git a/app/Models/Team.php b/app/Models/Team.php index 7cb1601de..a3dd4e473 100644 --- a/app/Models/Team.php +++ b/app/Models/Team.php @@ -177,9 +177,6 @@ class Team extends Model implements SendsDiscord, SendsEmail if (isCloud()) { return true; } - if (!data_get(auth()->user(), 'is_notification_notifications_enabled')) { - return true; - } if ($this->smtp_enabled || $this->resend_enabled || $this->discord_enabled || $this->telegram_enabled || $this->use_instance_email_settings) { return true; } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 0e9be72d1..a6ded1dc7 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -19,7 +19,10 @@ class EventServiceProvider extends ServiceProvider MaintenanceModeDisabled::class => [ MaintenanceModeDisabledNotification::class, ], - ProxyStarted::class => [ + \SocialiteProviders\Manager\SocialiteWasCalled::class => [ + \SocialiteProviders\Azure\AzureExtendSocialite::class.'@handle', + ], + ProxyStarted::class => [ ProxyStartedNotification::class, ], ]; diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php index 77de80885..6bb284eef 100644 --- a/app/Providers/FortifyServiceProvider.php +++ b/app/Providers/FortifyServiceProvider.php @@ -7,6 +7,7 @@ use App\Actions\Fortify\ResetUserPassword; use App\Actions\Fortify\UpdateUserPassword; use App\Actions\Fortify\UpdateUserProfileInformation; use App\Models\InstanceSettings; +use App\Models\OauthSetting; use App\Models\User; use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Http\Request; @@ -56,13 +57,15 @@ class FortifyServiceProvider extends ServiceProvider Fortify::loginView(function () { $settings = InstanceSettings::get(); + $enabled_oauth_providers = OauthSetting::where('enabled', true)->get(); $users = User::count(); if ($users == 0) { // If there are no users, redirect to registration return redirect()->route('register'); } return view('auth.login', [ - 'is_registration_enabled' => $settings->is_registration_enabled + 'is_registration_enabled' => $settings->is_registration_enabled, + 'enabled_oauth_providers' => $enabled_oauth_providers, ]); }); diff --git a/app/View/Components/Forms/Button.php b/app/View/Components/Forms/Button.php index c9f4ebdc0..06681910e 100644 --- a/app/View/Components/Forms/Button.php +++ b/app/View/Components/Forms/Button.php @@ -13,10 +13,9 @@ class Button extends Component */ public function __construct( public bool $disabled = false, - public bool $isModal = false, public bool $noStyle = false, public ?string $modalId = null, - public string $defaultClass = "btn btn-primary btn-sm font-normal text-white normal-case no-animation rounded border-none" + public string $defaultClass = "button" ) { if ($this->noStyle) { $this->defaultClass = ""; diff --git a/app/View/Components/Forms/Checkbox.php b/app/View/Components/Forms/Checkbox.php index 0bbbc1e04..95fe2d4f4 100644 --- a/app/View/Components/Forms/Checkbox.php +++ b/app/View/Components/Forms/Checkbox.php @@ -12,14 +12,14 @@ class Checkbox extends Component * Create a new component instance. */ public function __construct( - public string|null $id = null, - public string|null $name = null, - public string|null $value = null, - public string|null $label = null, - public string|null $helper = null, - public string|bool $instantSave = false, + public ?string $id = null, + public ?string $name = null, + public ?string $value = null, + public ?string $label = null, + public ?string $helper = null, + public string|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 string $defaultClass = "dark:border-neutral-700 text-coolgray-400 focus:ring-warning dark:bg-coolgray-100 rounded cursor-pointer dark:disabled:bg-base dark:disabled:cursor-not-allowed", ) { // } diff --git a/app/View/Components/Forms/Input.php b/app/View/Components/Forms/Input.php index a55f9b9d2..45f8e9678 100644 --- a/app/View/Components/Forms/Input.php +++ b/app/View/Components/Forms/Input.php @@ -21,7 +21,7 @@ class Input extends Component public ?string $helper = null, public bool $allowToPeak = true, public bool $isMultiline = false, - public string $defaultClass = "input input-sm bg-coolgray-100 rounded text-white w-full disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500 read-only:text-neutral-500 read-only:bg-coolgray-200/50" + public string $defaultClass = "input", ) { } @@ -29,7 +29,9 @@ class Input extends Component { if (is_null($this->id)) $this->id = new Cuid2(7); if (is_null($this->name)) $this->name = $this->id; - + if ($this->type === 'password') { + $this->defaultClass = $this->defaultClass . " pr-[2.8rem]"; + } // $this->label = Str::title($this->label); return view('components.forms.input'); } diff --git a/app/View/Components/Forms/Select.php b/app/View/Components/Forms/Select.php index e1f2fc759..40279bea6 100644 --- a/app/View/Components/Forms/Select.php +++ b/app/View/Components/Forms/Select.php @@ -14,12 +14,12 @@ class Select extends Component * Create a new component instance. */ public function __construct( - public string|null $id = null, - 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-sm bg-coolgray-100 font-normal disabled:bg-coolgray-200/50 disabled:border-none" + public ?string $id = null, + public ?string $name = null, + public ?string $label = null, + public ?string $helper = null, + public bool $required = false, + public string $defaultClass = "select" ) { // } diff --git a/app/View/Components/Forms/Textarea.php b/app/View/Components/Forms/Textarea.php index 8c50af533..95e0ef5d2 100644 --- a/app/View/Components/Forms/Textarea.php +++ b/app/View/Components/Forms/Textarea.php @@ -25,8 +25,8 @@ class Textarea extends Component public ?string $helper = null, public bool $realtimeValidation = false, public bool $allowToPeak = true, - public string $defaultClass = "textarea leading-normal bg-coolgray-100 rounded text-white w-full scrollbar disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500 read-only:text-neutral-500 read-only:bg-coolgray-200/50", - public string $defaultClassInput = "input input-sm bg-coolgray-100 rounded text-white w-full disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500 read-only:text-neutral-500 read-only:bg-coolgray-200/50" + public string $defaultClass = "input scrollbar", + public string $defaultClassInput = "input" ) { // } diff --git a/bootstrap/helpers/constants.php b/bootstrap/helpers/constants.php index 134cc6aad..84997d134 100644 --- a/bootstrap/helpers/constants.php +++ b/bootstrap/helpers/constants.php @@ -27,7 +27,8 @@ const DATABASE_DOCKER_IMAGES = [ 'couchdb', 'neo4j', 'influxdb', - 'clickhouse/clickhouse-server' + 'clickhouse/clickhouse-server', + 'supabase/postgres' ]; const SPECIFIC_SERVICES = [ 'quay.io/minio/minio', diff --git a/bootstrap/helpers/services.php b/bootstrap/helpers/services.php index dd05c67eb..7cb8595db 100644 --- a/bootstrap/helpers/services.php +++ b/bootstrap/helpers/services.php @@ -94,7 +94,7 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource) $resource->service->docker_compose_raw = $dockerComposeRaw; $resource->service->save(); - if (!str($resource->fqdn)->contains(',')) { + if ($resource->fqdn && !str($resource->fqdn)->contains(',')) { // Update FQDN $variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper(); $generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first(); diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index c9f98e48a..bfff8098a 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -280,6 +280,10 @@ function base_url(bool $withPort = true): string return url('/'); } +function isSubscribed() +{ + return auth()->user()->currentTeam()->subscription()->exists() || auth()->user()->isInstanceAdmin(); +} function isDev(): bool { return config('app.env') === 'local'; @@ -429,7 +433,7 @@ function sslip(Server $server) function getServiceTemplates() { - if (isDev()) { + if (!isDev()) { $services = File::get(base_path('templates/service-templates.json')); $services = collect(json_decode($services))->sortKeys(); } else { @@ -444,13 +448,6 @@ function getServiceTemplates() $services = collect([]); } } - // $version = config('version'); - // $services = $services->map(function ($service) use ($version) { - // if (version_compare($version, data_get($service, 'minVersion', '0.0.0'), '<')) { - // $service->disabled = true; - // } - // return $service; - // }); return $services; } @@ -1001,61 +998,63 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal 'service_id' => $resource->id, ])->first(); ['command' => $command, 'forService' => $forService, 'generatedValue' => $generatedValue, 'port' => $port] = parseEnvVariable($value); - if ($command?->value() === 'FQDN' || $command?->value() === 'URL') { - if (Str::lower($forService) === $serviceName) { - $fqdn = generateFqdn($resource->server, $containerName); - } else { - $fqdn = generateFqdn($resource->server, Str::lower($forService) . '-' . $resource->uuid); - } - if ($port) { - $fqdn = "$fqdn:$port"; - } - if ($foundEnv) { - $fqdn = data_get($foundEnv, 'value'); - } else { - if ($command->value() === 'URL') { - $fqdn = Str::of($fqdn)->after('://')->value(); + if (!is_null($command)) { + if ($command?->value() === 'FQDN' || $command?->value() === 'URL') { + if (Str::lower($forService) === $serviceName) { + $fqdn = generateFqdn($resource->server, $containerName); + } else { + $fqdn = generateFqdn($resource->server, Str::lower($forService) . '-' . $resource->uuid); } - EnvironmentVariable::create([ - 'key' => $key, - 'value' => $fqdn, - 'is_build_time' => false, - 'service_id' => $resource->id, - 'is_preview' => false, - ]); - } - if (!$isDatabase) { - if ($command->value() === 'FQDN' && is_null($savedService->fqdn) && !$foundEnv) { - $savedService->fqdn = $fqdn; - $savedService->save(); + if ($port) { + $fqdn = "$fqdn:$port"; } - // Caddy needs exact port in some cases. - if ($predefinedPort && !$key->endsWith("_{$predefinedPort}") && $command?->value() === 'FQDN' && $resource->server->proxyType() === 'CADDY') { - $env = EnvironmentVariable::where([ + if ($foundEnv) { + $fqdn = data_get($foundEnv, 'value'); + } else { + if ($command->value() === 'URL') { + $fqdn = Str::of($fqdn)->after('://')->value(); + } + EnvironmentVariable::create([ 'key' => $key, + 'value' => $fqdn, + 'is_build_time' => false, 'service_id' => $resource->id, - ])->first(); - if ($env) { - $env_url = Url::fromString($env->value); - $env_port = $env_url->getPort(); - if ($env_port !== $predefinedPort) { - $env_url = $env_url->withPort($predefinedPort); - $savedService->fqdn = $env_url->__toString(); - $savedService->save(); + 'is_preview' => false, + ]); + } + if (!$isDatabase) { + if ($command->value() === 'FQDN' && is_null($savedService->fqdn) && !$foundEnv) { + $savedService->fqdn = $fqdn; + $savedService->save(); + } + // Caddy needs exact port in some cases. + if ($predefinedPort && !$key->endsWith("_{$predefinedPort}") && $command?->value() === 'FQDN' && $resource->server->proxyType() === 'CADDY') { + $env = EnvironmentVariable::where([ + 'key' => $key, + 'service_id' => $resource->id, + ])->first(); + if ($env) { + $env_url = Url::fromString($env->value); + $env_port = $env_url->getPort(); + if ($env_port !== $predefinedPort) { + $env_url = $env_url->withPort($predefinedPort); + $savedService->fqdn = $env_url->__toString(); + $savedService->save(); + } } } } - } - } else { - $generatedValue = generateEnvValue($command, $resource); - if (!$foundEnv) { - EnvironmentVariable::create([ - 'key' => $key, - 'value' => $generatedValue, - 'is_build_time' => false, - 'service_id' => $resource->id, - 'is_preview' => false, - ]); + } else { + $generatedValue = generateEnvValue($command, $resource); + if (!$foundEnv) { + EnvironmentVariable::create([ + 'key' => $key, + 'value' => $generatedValue, + 'is_build_time' => false, + 'service_id' => $resource->id, + 'is_preview' => false, + ]); + } } } } else { @@ -1240,84 +1239,94 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal } $baseName = generateApplicationContainerName($resource, $pull_request_id); $containerName = "$serviceName-$baseName"; - if ($pull_request_id !== 0) { - if (count($serviceVolumes) > 0) { - $serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $pull_request_id, $topLevelVolumes) { - if (is_string($volume)) { - $volume = str($volume); - if ($volume->contains(':') && !$volume->startsWith('/')) { - $name = $volume->before(':'); - $mount = $volume->after(':'); - $newName = $resource->uuid . "-{$name}-pr-$pull_request_id"; - $volume = str("$newName:$mount"); - $topLevelVolumes->put($newName, [ - 'name' => $newName, - ]); - } - } else if (is_array($volume)) { - $source = data_get($volume, 'source'); - if ($source) { - $newSource = $resource->uuid . "-{$source}-pr-$pull_request_id"; - data_set($volume, 'source', $newSource); - if (!str($source)->startsWith('/')) { - $topLevelVolumes->put($newSource, [ - 'name' => $newSource, - ]); + if (count($serviceVolumes) > 0) { + $serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes, $pull_request_id) { + if (is_string($volume)) { + $volume = str($volume); + if ($volume->contains(':') && !$volume->startsWith('/')) { + $name = $volume->before(':'); + $mount = $volume->after(':'); + if ($name->startsWith('.') || $name->startsWith('~')) { + $dir = base_configuration_dir() . '/applications/' . $resource->uuid; + if ($name->startsWith('.')) { + $name = $name->replaceFirst('.', $dir); } - } - } - return $volume->value(); - }); - data_set($service, 'volumes', $serviceVolumes->toArray()); - } - } else { - if (count($serviceVolumes) > 0) { - $serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes) { - if (is_string($volume)) { - $volume = str($volume); - if ($volume->contains(':') && !$volume->startsWith('/')) { - $name = $volume->before(':'); - $mount = $volume->after(':'); - if ($name->startsWith('.') || $name->startsWith('~')) { - $dir = base_configuration_dir() . '/applications/' . $resource->uuid; - if ($name->startsWith('.')) { - $name = $name->replaceFirst('.', $dir); - } - if ($name->startsWith('~')) { - $name = $name->replaceFirst('~', $dir); - } + if ($name->startsWith('~')) { + $name = $name->replaceFirst('~', $dir); + } + if ($pull_request_id !== 0) { + $name = $name . "-pr-$pull_request_id"; + } + $volume = str("$name:$mount"); + } else { + if ($pull_request_id !== 0) { + $name = $name . "-pr-$pull_request_id"; $volume = str("$name:$mount"); + $topLevelVolumes->put($name, [ + 'name' => $name, + ]); } else { $topLevelVolumes->put($name->value(), [ 'name' => $name->value(), ]); } } - } else if (is_array($volume)) { - $source = data_get($volume, 'source'); - if ($source) { - if ((str($source)->startsWith('.') || str($source)->startsWith('~')) && !str($source)->startsWith('/')) { - $dir = base_configuration_dir() . '/applications/' . $resource->uuid; - if (str($source, '.')) { - $source = str('.', $dir, $source); - } - if (str($source, '~')) { - $source = str('~', $dir, $source); - } - data_set($volume, 'source', $source); + } else { + if ($volume->startsWith('/')) { + $name = $volume->before(':'); + $mount = $volume->after(':'); + if ($pull_request_id !== 0) { + $name = $name . "-pr-$pull_request_id"; + } + $volume = str("$name:$mount"); + } + } + } else if (is_array($volume)) { + $source = data_get($volume, 'source'); + $target = data_get($volume, 'target'); + $read_only = data_get($volume, 'read_only'); + if ($source && $target) { + if ((str($source)->startsWith('.') || str($source)->startsWith('~'))) { + $dir = base_configuration_dir() . '/applications/' . $resource->uuid; + if (str($source, '.')) { + $source = str($source)->replaceFirst('.', $dir); + } + if (str($source, '~')) { + $source = str($source)->replaceFirst('~', $dir); + } + if ($pull_request_id !== 0) { + $source = $source . "-pr-$pull_request_id"; + } + if ($read_only) { + data_set($volume, 'source', $source . ':' . $target . ':ro'); } else { - data_set($volume, 'source', $source); + data_set($volume, 'source', $source . ':' . $target); + } + } else { + if ($pull_request_id !== 0) { + $source = $source . "-pr-$pull_request_id"; + } + if ($read_only) { + data_set($volume, 'source', $source . ':' . $target . ':ro'); + } else { + data_set($volume, 'source', $source . ':' . $target); + } + if (!str($source)->startsWith('/')) { $topLevelVolumes->put($source, [ 'name' => $source, ]); } } } - return $volume->value(); - }); - data_set($service, 'volumes', $serviceVolumes->toArray()); - } + } + if (is_array($volume)) { + return data_get($volume, 'source'); + } + return $volume->value(); + }); + data_set($service, 'volumes', $serviceVolumes->toArray()); } + // Decide if the service is a database $isDatabase = isDatabaseImage(data_get_str($service, 'image')); data_set($service, 'is_database', $isDatabase); @@ -1457,39 +1466,41 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal 'application_id' => $resource->id, ])->first(); ['command' => $command, 'forService' => $forService, 'generatedValue' => $generatedValue, 'port' => $port] = parseEnvVariable($value); - if ($command?->value() === 'FQDN' || $command?->value() === 'URL') { - if (Str::lower($forService) === $serviceName) { - $fqdn = generateFqdn($server, $containerName); - } else { - $fqdn = generateFqdn($server, Str::lower($forService) . '-' . $resource->uuid); - } - if ($port) { - $fqdn = "$fqdn:$port"; - } - if ($foundEnv) { - $fqdn = data_get($foundEnv, 'value'); - } else { - if ($command->value() === 'URL') { - $fqdn = Str::of($fqdn)->after('://')->value(); + if (!is_null($command)) { + if ($command?->value() === 'FQDN' || $command?->value() === 'URL') { + if (Str::lower($forService) === $serviceName) { + $fqdn = generateFqdn($server, $containerName); + } else { + $fqdn = generateFqdn($server, Str::lower($forService) . '-' . $resource->uuid); + } + if ($port) { + $fqdn = "$fqdn:$port"; + } + if ($foundEnv) { + $fqdn = data_get($foundEnv, 'value'); + } else { + if ($command?->value() === 'URL') { + $fqdn = Str::of($fqdn)->after('://')->value(); + } + EnvironmentVariable::create([ + 'key' => $key, + 'value' => $fqdn, + 'is_build_time' => false, + 'application_id' => $resource->id, + 'is_preview' => false, + ]); + } + } else { + $generatedValue = generateEnvValue($command); + if (!$foundEnv) { + EnvironmentVariable::create([ + 'key' => $key, + 'value' => $generatedValue, + 'is_build_time' => false, + 'application_id' => $resource->id, + 'is_preview' => false, + ]); } - EnvironmentVariable::create([ - 'key' => $key, - 'value' => $fqdn, - 'is_build_time' => false, - 'application_id' => $resource->id, - 'is_preview' => false, - ]); - } - } else { - $generatedValue = generateEnvValue($command); - if (!$foundEnv) { - EnvironmentVariable::create([ - 'key' => $key, - 'value' => $generatedValue, - 'is_build_time' => false, - 'application_id' => $resource->id, - 'is_preview' => false, - ]); } } } else { @@ -1602,6 +1613,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal return $service; }); + if ($pull_request_id !== 0) { + $services->each(function ($service, $serviceName) use ($pull_request_id, $services) { + $services[$serviceName . "-pr-$pull_request_id"] = $service; + data_forget($services, $serviceName); + }); + } $finalServices = [ 'version' => $dockerComposeVersion, 'services' => $services->toArray(), @@ -1635,29 +1652,30 @@ function parseEnvVariable(Str|string $value) $forService = null; $generatedValue = null; $port = null; - - if ($count === 2) { - if ($value->startsWith('SERVICE_FQDN') || $value->startsWith('SERVICE_URL')) { - // SERVICE_FQDN_UMAMI - $command = $value->after('SERVICE_')->beforeLast('_'); - $forService = $value->afterLast('_'); - } else { - // SERVICE_BASE64_UMAMI - $command = $value->after('SERVICE_')->beforeLast('_'); - } - } - if ($count === 3) { - if ($value->startsWith('SERVICE_FQDN') || $value->startsWith('SERVICE_URL')) { - // SERVICE_FQDN_UMAMI_1000 - $command = $value->after('SERVICE_')->before('_'); - $forService = $value->after('SERVICE_')->after('_')->before('_'); - $port = $value->afterLast('_'); - if (filter_var($port, FILTER_VALIDATE_INT) === false) { - $port = null; + if ($value->startsWith('SERVICE')) { + if ($count === 2) { + if ($value->startsWith('SERVICE_FQDN') || $value->startsWith('SERVICE_URL')) { + // SERVICE_FQDN_UMAMI + $command = $value->after('SERVICE_')->beforeLast('_'); + $forService = $value->afterLast('_'); + } else { + // SERVICE_BASE64_UMAMI + $command = $value->after('SERVICE_')->beforeLast('_'); + } + } + if ($count === 3) { + if ($value->startsWith('SERVICE_FQDN') || $value->startsWith('SERVICE_URL')) { + // SERVICE_FQDN_UMAMI_1000 + $command = $value->after('SERVICE_')->before('_'); + $forService = $value->after('SERVICE_')->after('_')->before('_'); + $port = $value->afterLast('_'); + if (filter_var($port, FILTER_VALIDATE_INT) === false) { + $port = null; + } + } else { + // SERVICE_BASE64_64_UMAMI + $command = $value->after('SERVICE_')->beforeLast('_'); } - } else { - // SERVICE_BASE64_64_UMAMI - $command = $value->after('SERVICE_')->beforeLast('_'); } } return [ diff --git a/bootstrap/helpers/socialite.php b/bootstrap/helpers/socialite.php new file mode 100644 index 000000000..0798717e8 --- /dev/null +++ b/bootstrap/helpers/socialite.php @@ -0,0 +1,37 @@ +client_id, + $oauth_setting->client_secret, + $oauth_setting->redirect_uri, + ['tenant' => $oauth_setting->tenant], + ); + return Socialite::driver('azure')->setConfig($azure_config); + } + + $config = [ + 'client_id' => $oauth_setting->client_id, + 'client_secret' => $oauth_setting->client_secret, + 'redirect' => $oauth_setting->redirect_uri, + ]; + + $provider_class_map = [ + 'bitbucket' => \Laravel\Socialite\Two\BitbucketProvider::class, + 'github' => \Laravel\Socialite\Two\GithubProvider::class, + 'gitlab' => \Laravel\Socialite\Two\GitlabProvider::class, + 'google' => \Laravel\Socialite\Two\GoogleProvider::class, + ]; + + return Socialite::buildProvider( + $provider_class_map[$provider], + $config + ); +} diff --git a/composer.json b/composer.json index f762ed579..1624e1390 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ "laravel/horizon": "^5.15", "laravel/prompts": "^0.1.6", "laravel/sanctum": "^v3.2.1", + "laravel/socialite": "^5.12", "laravel/tinker": "^v2.8.1", "laravel/ui": "^4.2", "lcobucci/jwt": "^5.0.0", @@ -31,6 +32,7 @@ "pusher/pusher-php-server": "^7.2", "resend/resend-laravel": "^0.5.0", "sentry/sentry-laravel": "^3.4", + "socialiteproviders/microsoft-azure": "^5.1", "spatie/laravel-activitylog": "^4.7.3", "spatie/laravel-data": "^3.4.3", "spatie/laravel-ray": "^1.32.4", diff --git a/composer.lock b/composer.lock index 74b27137f..1c52be3ab 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": "19b19082b605e09867e6ae65fb8135f6", + "content-hash": "9bdaf702cdd870434444f8937a816fdb", "packages": [ { "name": "amphp/amp", @@ -317,21 +317,22 @@ }, { "name": "amphp/parallel", - "version": "v2.2.6", + "version": "v2.2.9", "source": { "type": "git", "url": "https://github.com/amphp/parallel.git", - "reference": "5aeaad20297507cc754859236720501b54306eba" + "reference": "73d293f1fc4df1bebc3c4fce1432e82dd7032238" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parallel/zipball/5aeaad20297507cc754859236720501b54306eba", - "reference": "5aeaad20297507cc754859236720501b54306eba", + "url": "https://api.github.com/repos/amphp/parallel/zipball/73d293f1fc4df1bebc3c4fce1432e82dd7032238", + "reference": "73d293f1fc4df1bebc3c4fce1432e82dd7032238", "shasum": "" }, "require": { "amphp/amp": "^3", "amphp/byte-stream": "^2", + "amphp/cache": "^2", "amphp/parser": "^1", "amphp/pipeline": "^1", "amphp/process": "^2", @@ -388,7 +389,7 @@ ], "support": { "issues": "https://github.com/amphp/parallel/issues", - "source": "https://github.com/amphp/parallel/tree/v2.2.6" + "source": "https://github.com/amphp/parallel/tree/v2.2.9" }, "funding": [ { @@ -396,20 +397,20 @@ "type": "github" } ], - "time": "2024-01-07T18:12:13+00:00" + "time": "2024-03-24T18:27:44+00:00" }, { "name": "amphp/parser", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/amphp/parser.git", - "reference": "ff1de4144726c5dad5fab97f66692ebe8de3e151" + "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parser/zipball/ff1de4144726c5dad5fab97f66692ebe8de3e151", - "reference": "ff1de4144726c5dad5fab97f66692ebe8de3e151", + "url": "https://api.github.com/repos/amphp/parser/zipball/3cf1f8b32a0171d4b1bed93d25617637a77cded7", + "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7", "shasum": "" }, "require": { @@ -450,7 +451,7 @@ ], "support": { "issues": "https://github.com/amphp/parser/issues", - "source": "https://github.com/amphp/parser/tree/v1.1.0" + "source": "https://github.com/amphp/parser/tree/v1.1.1" }, "funding": [ { @@ -458,20 +459,20 @@ "type": "github" } ], - "time": "2022-12-30T18:08:47+00:00" + "time": "2024-03-21T19:16:53+00:00" }, { "name": "amphp/pipeline", - "version": "v1.1.0", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/amphp/pipeline.git", - "reference": "8a0ecc281bb0932d6b4a786453aff18c55756e63" + "reference": "f1c2ce35d27ae86ead018adb803eccca7421dd9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/pipeline/zipball/8a0ecc281bb0932d6b4a786453aff18c55756e63", - "reference": "8a0ecc281bb0932d6b4a786453aff18c55756e63", + "url": "https://api.github.com/repos/amphp/pipeline/zipball/f1c2ce35d27ae86ead018adb803eccca7421dd9b", + "reference": "f1c2ce35d27ae86ead018adb803eccca7421dd9b", "shasum": "" }, "require": { @@ -517,7 +518,7 @@ ], "support": { "issues": "https://github.com/amphp/pipeline/issues", - "source": "https://github.com/amphp/pipeline/tree/v1.1.0" + "source": "https://github.com/amphp/pipeline/tree/v1.2.0" }, "funding": [ { @@ -525,7 +526,7 @@ "type": "github" } ], - "time": "2023-12-23T04:34:28+00:00" + "time": "2024-03-10T14:48:16+00:00" }, { "name": "amphp/process", @@ -655,16 +656,16 @@ }, { "name": "amphp/socket", - "version": "v2.2.4", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/amphp/socket.git", - "reference": "4223324c627cc26d44800630411e64856d3344bc" + "reference": "acc0a2f65ab498025ba5641f7cce499c4b1ed4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/socket/zipball/4223324c627cc26d44800630411e64856d3344bc", - "reference": "4223324c627cc26d44800630411e64856d3344bc", + "url": "https://api.github.com/repos/amphp/socket/zipball/acc0a2f65ab498025ba5641f7cce499c4b1ed4b5", + "reference": "acc0a2f65ab498025ba5641f7cce499c4b1ed4b5", "shasum": "" }, "require": { @@ -727,7 +728,7 @@ ], "support": { "issues": "https://github.com/amphp/socket/issues", - "source": "https://github.com/amphp/socket/tree/v2.2.4" + "source": "https://github.com/amphp/socket/tree/v2.3.0" }, "funding": [ { @@ -735,20 +736,20 @@ "type": "github" } ], - "time": "2024-02-28T15:56:06+00:00" + "time": "2024-03-19T20:01:53+00:00" }, { "name": "amphp/sync", - "version": "v2.1.0", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/amphp/sync.git", - "reference": "50ddc7392cc8034b3e4798cef3cc90d3f4c0441c" + "reference": "375ef5b54a0d12c38e12728dde05a55e30f2fbec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/sync/zipball/50ddc7392cc8034b3e4798cef3cc90d3f4c0441c", - "reference": "50ddc7392cc8034b3e4798cef3cc90d3f4c0441c", + "url": "https://api.github.com/repos/amphp/sync/zipball/375ef5b54a0d12c38e12728dde05a55e30f2fbec", + "reference": "375ef5b54a0d12c38e12728dde05a55e30f2fbec", "shasum": "" }, "require": { @@ -762,7 +763,7 @@ "amphp/php-cs-fixer-config": "^2", "amphp/phpunit-util": "^3", "phpunit/phpunit": "^9", - "psalm/phar": "^5.4" + "psalm/phar": "5.23" }, "type": "library", "autoload": { @@ -802,7 +803,7 @@ ], "support": { "issues": "https://github.com/amphp/sync/issues", - "source": "https://github.com/amphp/sync/tree/v2.1.0" + "source": "https://github.com/amphp/sync/tree/v2.2.0" }, "funding": [ { @@ -810,7 +811,7 @@ "type": "github" } ], - "time": "2023-08-19T13:53:40+00:00" + "time": "2024-03-12T01:00:01+00:00" }, { "name": "amphp/windows-registry", @@ -920,16 +921,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.300.10", + "version": "3.301.6", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "b24bf7882fed0ef029996dcdcba6c273b69db8fe" + "reference": "18c0ebd71d3071304f1ea02aa9af75f95863177a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/b24bf7882fed0ef029996dcdcba6c273b69db8fe", - "reference": "b24bf7882fed0ef029996dcdcba6c273b69db8fe", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/18c0ebd71d3071304f1ea02aa9af75f95863177a", + "reference": "18c0ebd71d3071304f1ea02aa9af75f95863177a", "shasum": "" }, "require": { @@ -1009,9 +1010,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.300.10" + "source": "https://github.com/aws/aws-sdk-php/tree/3.301.6" }, - "time": "2024-03-04T19:06:07+00:00" + "time": "2024-03-22T18:05:21+00:00" }, { "name": "bacon/bacon-qr-code", @@ -2724,16 +2725,16 @@ }, { "name": "jean85/pretty-package-versions", - "version": "2.0.5", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af" + "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/ae547e455a3d8babd07b96966b17d7fd21d9c6af", - "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/f9fdd29ad8e6d024f52678b570e5593759b550b4", + "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4", "shasum": "" }, "require": { @@ -2741,9 +2742,9 @@ "php": "^7.1|^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.17", + "friendsofphp/php-cs-fixer": "^3.2", "jean85/composer-provided-replaced-stub-package": "^1.0", - "phpstan/phpstan": "^0.12.66", + "phpstan/phpstan": "^1.4", "phpunit/phpunit": "^7.5|^8.5|^9.4", "vimeo/psalm": "^4.3" }, @@ -2777,9 +2778,9 @@ ], "support": { "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.5" + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.6" }, - "time": "2021-10-08T21:21:46+00:00" + "time": "2024-03-08T09:58:59+00:00" }, { "name": "kelunik/certificate", @@ -2841,16 +2842,16 @@ }, { "name": "laravel/fortify", - "version": "v1.20.1", + "version": "v1.21.0", "source": { "type": "git", "url": "https://github.com/laravel/fortify.git", - "reference": "ab1a76991a32be21448156419ddc7eb4731b0a8b" + "reference": "b34e672e1d341f6e520f81712f73e56f6cb80767" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/fortify/zipball/ab1a76991a32be21448156419ddc7eb4731b0a8b", - "reference": "ab1a76991a32be21448156419ddc7eb4731b0a8b", + "url": "https://api.github.com/repos/laravel/fortify/zipball/b34e672e1d341f6e520f81712f73e56f6cb80767", + "reference": "b34e672e1d341f6e520f81712f73e56f6cb80767", "shasum": "" }, "require": { @@ -2901,20 +2902,20 @@ "issues": "https://github.com/laravel/fortify/issues", "source": "https://github.com/laravel/fortify" }, - "time": "2024-02-08T14:36:46+00:00" + "time": "2024-03-08T19:55:45+00:00" }, { "name": "laravel/framework", - "version": "v10.46.0", + "version": "v10.48.4", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "5e95946a8283a8d5c015035793f9c61c297e937f" + "reference": "7e0701bf59cb76a51f7c1f7bea51c0c0c29c0b72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/5e95946a8283a8d5c015035793f9c61c297e937f", - "reference": "5e95946a8283a8d5c015035793f9c61c297e937f", + "url": "https://api.github.com/repos/laravel/framework/zipball/7e0701bf59cb76a51f7c1f7bea51c0c0c29c0b72", + "reference": "7e0701bf59cb76a51f7c1f7bea51c0c0c29c0b72", "shasum": "" }, "require": { @@ -2962,6 +2963,7 @@ "conflict": { "carbonphp/carbon-doctrine-types": ">=3.0", "doctrine/dbal": ">=4.0", + "mockery/mockery": "1.6.8", "phpunit/phpunit": ">=11.0.0", "tightenco/collect": "<5.5.33" }, @@ -3018,7 +3020,7 @@ "league/flysystem-sftp-v3": "^3.0", "mockery/mockery": "^1.5.1", "nyholm/psr7": "^1.2", - "orchestra/testbench-core": "^8.18", + "orchestra/testbench-core": "^8.23.4", "pda/pheanstalk": "^4.0", "phpstan/phpstan": "^1.4.7", "phpunit/phpunit": "^10.0.7", @@ -3107,7 +3109,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-02-27T16:46:54+00:00" + "time": "2024-03-21T13:36:36+00:00" }, { "name": "laravel/horizon", @@ -3370,6 +3372,76 @@ }, "time": "2023-11-08T14:08:06+00:00" }, + { + "name": "laravel/socialite", + "version": "v5.12.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/socialite.git", + "reference": "7dae1b072573809f32ab6dcf4aebb57c8b3e8acf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/socialite/zipball/7dae1b072573809f32ab6dcf4aebb57c8b3e8acf", + "reference": "7dae1b072573809f32ab6dcf4aebb57c8b3e8acf", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "league/oauth1-client": "^1.10.1", + "php": "^7.2|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0|^8.0|^9.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.0|^9.3|^10.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Socialite\\SocialiteServiceProvider" + ], + "aliases": { + "Socialite": "Laravel\\Socialite\\Facades\\Socialite" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.", + "homepage": "https://laravel.com", + "keywords": [ + "laravel", + "oauth" + ], + "support": { + "issues": "https://github.com/laravel/socialite/issues", + "source": "https://github.com/laravel/socialite" + }, + "time": "2024-02-16T08:58:20+00:00" + }, { "name": "laravel/tinker", "version": "v2.9.0", @@ -3438,16 +3510,16 @@ }, { "name": "laravel/ui", - "version": "v4.4.0", + "version": "v4.5.0", "source": { "type": "git", "url": "https://github.com/laravel/ui.git", - "reference": "7335d7049b2cde345c029e9d2de839b80af62bc0" + "reference": "da3811f409297d13feccd5858ce748e7474b3d11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/ui/zipball/7335d7049b2cde345c029e9d2de839b80af62bc0", - "reference": "7335d7049b2cde345c029e9d2de839b80af62bc0", + "url": "https://api.github.com/repos/laravel/ui/zipball/da3811f409297d13feccd5858ce748e7474b3d11", + "reference": "da3811f409297d13feccd5858ce748e7474b3d11", "shasum": "" }, "require": { @@ -3458,8 +3530,8 @@ "php": "^8.0" }, "require-dev": { - "orchestra/testbench": "^7.0|^8.0|^9.0", - "phpunit/phpunit": "^9.3|^10.4" + "orchestra/testbench": "^7.35|^8.15|^9.0", + "phpunit/phpunit": "^9.3|^10.4|^11.0" }, "type": "library", "extra": { @@ -3494,9 +3566,9 @@ "ui" ], "support": { - "source": "https://github.com/laravel/ui/tree/v4.4.0" + "source": "https://github.com/laravel/ui/tree/v4.5.0" }, - "time": "2024-01-12T15:56:45+00:00" + "time": "2024-03-04T13:58:27+00:00" }, { "name": "lcobucci/jwt", @@ -3761,16 +3833,16 @@ }, { "name": "league/flysystem", - "version": "3.24.0", + "version": "3.25.1", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "b25a361508c407563b34fac6f64a8a17a8819675" + "reference": "abbd664eb4381102c559d358420989f835208f18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/b25a361508c407563b34fac6f64a8a17a8819675", - "reference": "b25a361508c407563b34fac6f64a8a17a8819675", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/abbd664eb4381102c559d358420989f835208f18", + "reference": "abbd664eb4381102c559d358420989f835208f18", "shasum": "" }, "require": { @@ -3798,7 +3870,7 @@ "friendsofphp/php-cs-fixer": "^3.5", "google/cloud-storage": "^1.23", "microsoft/azure-storage-blob": "^1.1", - "phpseclib/phpseclib": "^3.0.34", + "phpseclib/phpseclib": "^3.0.36", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.5.11|^10.0", "sabre/dav": "^4.6.0" @@ -3835,7 +3907,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.24.0" + "source": "https://github.com/thephpleague/flysystem/tree/3.25.1" }, "funding": [ { @@ -3847,20 +3919,20 @@ "type": "github" } ], - "time": "2024-02-04T12:10:17+00:00" + "time": "2024-03-16T12:53:19+00:00" }, { "name": "league/flysystem-aws-s3-v3", - "version": "3.24.0", + "version": "3.25.1", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", - "reference": "809474e37b7fb1d1f8bcc0f8a98bc1cae99aa513" + "reference": "6a5be0e6d6a93574e80805c9cc108a4b63c824d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/809474e37b7fb1d1f8bcc0f8a98bc1cae99aa513", - "reference": "809474e37b7fb1d1f8bcc0f8a98bc1cae99aa513", + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/6a5be0e6d6a93574e80805c9cc108a4b63c824d8", + "reference": "6a5be0e6d6a93574e80805c9cc108a4b63c824d8", "shasum": "" }, "require": { @@ -3900,7 +3972,7 @@ "storage" ], "support": { - "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.24.0" + "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.25.1" }, "funding": [ { @@ -3912,20 +3984,20 @@ "type": "github" } ], - "time": "2024-01-26T18:43:21+00:00" + "time": "2024-03-15T19:58:44+00:00" }, { "name": "league/flysystem-local", - "version": "3.23.1", + "version": "3.25.1", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "b884d2bf9b53bb4804a56d2df4902bb51e253f00" + "reference": "61a6a90d6e999e4ddd9ce5adb356de0939060b92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/b884d2bf9b53bb4804a56d2df4902bb51e253f00", - "reference": "b884d2bf9b53bb4804a56d2df4902bb51e253f00", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/61a6a90d6e999e4ddd9ce5adb356de0939060b92", + "reference": "61a6a90d6e999e4ddd9ce5adb356de0939060b92", "shasum": "" }, "require": { @@ -3959,8 +4031,7 @@ "local" ], "support": { - "issues": "https://github.com/thephpleague/flysystem-local/issues", - "source": "https://github.com/thephpleague/flysystem-local/tree/3.23.1" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.25.1" }, "funding": [ { @@ -3972,20 +4043,20 @@ "type": "github" } ], - "time": "2024-01-26T18:25:23+00:00" + "time": "2024-03-15T19:58:44+00:00" }, { "name": "league/flysystem-sftp-v3", - "version": "3.23.1", + "version": "3.25.1", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-sftp-v3.git", - "reference": "09d001860d6642e2bed75f9d2f9e9fa931a3a6be" + "reference": "5cf169f33e4351832373f9d1b663c137589aa260" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-sftp-v3/zipball/09d001860d6642e2bed75f9d2f9e9fa931a3a6be", - "reference": "09d001860d6642e2bed75f9d2f9e9fa931a3a6be", + "url": "https://api.github.com/repos/thephpleague/flysystem-sftp-v3/zipball/5cf169f33e4351832373f9d1b663c137589aa260", + "reference": "5cf169f33e4351832373f9d1b663c137589aa260", "shasum": "" }, "require": { @@ -4019,8 +4090,7 @@ "sftp" ], "support": { - "issues": "https://github.com/thephpleague/flysystem-sftp-v3/issues", - "source": "https://github.com/thephpleague/flysystem-sftp-v3/tree/3.23.1" + "source": "https://github.com/thephpleague/flysystem-sftp-v3/tree/3.25.1" }, "funding": [ { @@ -4032,7 +4102,7 @@ "type": "github" } ], - "time": "2024-01-26T18:25:23+00:00" + "time": "2024-03-16T11:44:18+00:00" }, { "name": "league/mime-type-detection", @@ -4091,17 +4161,93 @@ "time": "2024-01-28T23:22:08+00:00" }, { - "name": "league/uri", - "version": "7.4.0", + "name": "league/oauth1-client", + "version": "v1.10.1", "source": { "type": "git", - "url": "https://github.com/thephpleague/uri.git", - "reference": "bf414ba956d902f5d98bf9385fcf63954f09dce5" + "url": "https://github.com/thephpleague/oauth1-client.git", + "reference": "d6365b901b5c287dd41f143033315e2f777e1167" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/bf414ba956d902f5d98bf9385fcf63954f09dce5", - "reference": "bf414ba956d902f5d98bf9385fcf63954f09dce5", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/d6365b901b5c287dd41f143033315e2f777e1167", + "reference": "d6365b901b5c287dd41f143033315e2f777e1167", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "guzzlehttp/psr7": "^1.7|^2.0", + "php": ">=7.1||>=8.0" + }, + "require-dev": { + "ext-simplexml": "*", + "friendsofphp/php-cs-fixer": "^2.17", + "mockery/mockery": "^1.3.3", + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5||9.5" + }, + "suggest": { + "ext-simplexml": "For decoding XML-based responses." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev", + "dev-develop": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth1\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Corlett", + "email": "bencorlett@me.com", + "homepage": "http://www.webcomm.com.au", + "role": "Developer" + } + ], + "description": "OAuth 1.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "bitbucket", + "identity", + "idp", + "oauth", + "oauth1", + "single sign on", + "trello", + "tumblr", + "twitter" + ], + "support": { + "issues": "https://github.com/thephpleague/oauth1-client/issues", + "source": "https://github.com/thephpleague/oauth1-client/tree/v1.10.1" + }, + "time": "2022-04-15T14:02:14+00:00" + }, + { + "name": "league/uri", + "version": "7.4.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "bedb6e55eff0c933668addaa7efa1e1f2c417cc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/bedb6e55eff0c933668addaa7efa1e1f2c417cc4", + "reference": "bedb6e55eff0c933668addaa7efa1e1f2c417cc4", "shasum": "" }, "require": { @@ -4170,7 +4316,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.4.0" + "source": "https://github.com/thephpleague/uri/tree/7.4.1" }, "funding": [ { @@ -4178,20 +4324,20 @@ "type": "github" } ], - "time": "2023-12-01T06:24:25+00:00" + "time": "2024-03-23T07:42:40+00:00" }, { "name": "league/uri-interfaces", - "version": "7.4.0", + "version": "7.4.1", "source": { "type": "git", "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "bd8c487ec236930f7bbc42b8d374fa882fbba0f3" + "reference": "8d43ef5c841032c87e2de015972c06f3865ef718" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/bd8c487ec236930f7bbc42b8d374fa882fbba0f3", - "reference": "bd8c487ec236930f7bbc42b8d374fa882fbba0f3", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/8d43ef5c841032c87e2de015972c06f3865ef718", + "reference": "8d43ef5c841032c87e2de015972c06f3865ef718", "shasum": "" }, "require": { @@ -4254,7 +4400,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.4.0" + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.4.1" }, "funding": [ { @@ -4262,20 +4408,20 @@ "type": "github" } ], - "time": "2023-11-24T15:40:42+00:00" + "time": "2024-03-23T07:42:40+00:00" }, { "name": "livewire/livewire", - "version": "v3.4.6", + "version": "v3.4.9", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "7e7d638183b34fb61621455891869f5abfd55a82" + "reference": "c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/7e7d638183b34fb61621455891869f5abfd55a82", - "reference": "7e7d638183b34fb61621455891869f5abfd55a82", + "url": "https://api.github.com/repos/livewire/livewire/zipball/c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0", + "reference": "c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0", "shasum": "" }, "require": { @@ -4329,7 +4475,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.4.6" + "source": "https://github.com/livewire/livewire/tree/v3.4.9" }, "funding": [ { @@ -4337,31 +4483,31 @@ "type": "github" } ], - "time": "2024-02-20T14:04:25+00:00" + "time": "2024-03-14T14:03:32+00:00" }, { "name": "lorisleiva/laravel-actions", - "version": "v2.7.3", + "version": "v2.8.0", "source": { "type": "git", "url": "https://github.com/lorisleiva/laravel-actions.git", - "reference": "5d2e2a670ad758496021943a8d6dea4014e213d6" + "reference": "d5c2ca544f40d85f877b38eb6d23e9c967ecb69f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lorisleiva/laravel-actions/zipball/5d2e2a670ad758496021943a8d6dea4014e213d6", - "reference": "5d2e2a670ad758496021943a8d6dea4014e213d6", + "url": "https://api.github.com/repos/lorisleiva/laravel-actions/zipball/d5c2ca544f40d85f877b38eb6d23e9c967ecb69f", + "reference": "d5c2ca544f40d85f877b38eb6d23e9c967ecb69f", "shasum": "" }, "require": { - "illuminate/contracts": "9.0 - 9.34 || ^9.36 || ^10.0", - "lorisleiva/lody": "^0.4", - "php": "^8.0" + "illuminate/contracts": "^10.0|^11.0", + "lorisleiva/lody": "^0.5", + "php": "^8.1" }, "require-dev": { - "orchestra/testbench": "^8.5", - "pestphp/pest": "^1.23", - "phpunit/phpunit": "^9.6" + "orchestra/testbench": "^9.0", + "pestphp/pest": "^1.23|^2.34", + "phpunit/phpunit": "^9.6|^10.0" }, "type": "library", "extra": { @@ -4404,7 +4550,7 @@ ], "support": { "issues": "https://github.com/lorisleiva/laravel-actions/issues", - "source": "https://github.com/lorisleiva/laravel-actions/tree/v2.7.3" + "source": "https://github.com/lorisleiva/laravel-actions/tree/v2.8.0" }, "funding": [ { @@ -4412,30 +4558,30 @@ "type": "github" } ], - "time": "2024-01-09T16:57:43+00:00" + "time": "2024-03-13T12:47:32+00:00" }, { "name": "lorisleiva/lody", - "version": "v0.4.0", + "version": "v0.5.0", "source": { "type": "git", "url": "https://github.com/lorisleiva/lody.git", - "reference": "1a43e8e423f3b2b64119542bc44a2071208fae16" + "reference": "c2f51b070e99f3a240d66cf68ef1f232036917fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lorisleiva/lody/zipball/1a43e8e423f3b2b64119542bc44a2071208fae16", - "reference": "1a43e8e423f3b2b64119542bc44a2071208fae16", + "url": "https://api.github.com/repos/lorisleiva/lody/zipball/c2f51b070e99f3a240d66cf68ef1f232036917fe", + "reference": "c2f51b070e99f3a240d66cf68ef1f232036917fe", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0|^9.0|^10.0", + "illuminate/contracts": "^9.0|^10.0|^11.0", "php": "^8.0" }, "require-dev": { - "orchestra/testbench": "^8.0", - "pestphp/pest": "^1.20.0", - "phpunit/phpunit": "^9.5.10" + "orchestra/testbench": "^9.0", + "pestphp/pest": "^1.20|^2.34", + "phpunit/phpunit": "^9.5.10|^10.5" }, "type": "library", "extra": { @@ -4476,7 +4622,7 @@ ], "support": { "issues": "https://github.com/lorisleiva/lody/issues", - "source": "https://github.com/lorisleiva/lody/tree/v0.4.0" + "source": "https://github.com/lorisleiva/lody/tree/v0.5.0" }, "funding": [ { @@ -4484,7 +4630,7 @@ "type": "github" } ], - "time": "2023-02-05T15:03:45+00:00" + "time": "2024-03-13T12:08:59+00:00" }, { "name": "monolog/monolog", @@ -4910,16 +5056,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.0.1", + "version": "v5.0.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69" + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2218c2252c874a4624ab2f613d86ac32d227bc69", - "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", "shasum": "" }, "require": { @@ -4962,9 +5108,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" }, - "time": "2024-02-21T19:24:10+00:00" + "time": "2024-03-05T20:51:40+00:00" }, { "name": "nubs/random-name-generator", @@ -5592,16 +5738,16 @@ }, { "name": "php-http/message", - "version": "1.16.0", + "version": "1.16.1", "source": { "type": "git", "url": "https://github.com/php-http/message.git", - "reference": "47a14338bf4ebd67d317bf1144253d7db4ab55fd" + "reference": "5997f3289332c699fa2545c427826272498a2088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/message/zipball/47a14338bf4ebd67d317bf1144253d7db4ab55fd", - "reference": "47a14338bf4ebd67d317bf1144253d7db4ab55fd", + "url": "https://api.github.com/repos/php-http/message/zipball/5997f3289332c699fa2545c427826272498a2088", + "reference": "5997f3289332c699fa2545c427826272498a2088", "shasum": "" }, "require": { @@ -5655,9 +5801,9 @@ ], "support": { "issues": "https://github.com/php-http/message/issues", - "source": "https://github.com/php-http/message/tree/1.16.0" + "source": "https://github.com/php-http/message/tree/1.16.1" }, - "time": "2023-05-17T06:43:38+00:00" + "time": "2024-03-07T13:22:09+00:00" }, { "name": "php-http/message-factory", @@ -5716,16 +5862,16 @@ }, { "name": "php-http/promise", - "version": "1.3.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/php-http/promise.git", - "reference": "2916a606d3b390f4e9e8e2b8dd68581508be0f07" + "reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/promise/zipball/2916a606d3b390f4e9e8e2b8dd68581508be0f07", - "reference": "2916a606d3b390f4e9e8e2b8dd68581508be0f07", + "url": "https://api.github.com/repos/php-http/promise/zipball/fc85b1fba37c169a69a07ef0d5a8075770cc1f83", + "reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83", "shasum": "" }, "require": { @@ -5762,9 +5908,9 @@ ], "support": { "issues": "https://github.com/php-http/promise/issues", - "source": "https://github.com/php-http/promise/tree/1.3.0" + "source": "https://github.com/php-http/promise/tree/1.3.1" }, - "time": "2024-01-04T18:49:48+00:00" + "time": "2024-03-15T13:55:21+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -6064,16 +6210,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.26.0", + "version": "1.27.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "231e3186624c03d7e7c890ec662b81e6b0405227" + "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/231e3186624c03d7e7c890ec662b81e6b0405227", - "reference": "231e3186624c03d7e7c890ec662b81e6b0405227", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/86e4d5a4b036f8f0be1464522f4c6b584c452757", + "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757", "shasum": "" }, "require": { @@ -6105,22 +6251,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.26.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.27.0" }, - "time": "2024-02-23T16:05:55+00:00" + "time": "2024-03-21T13:14:53+00:00" }, { "name": "phpstan/phpstan", - "version": "1.10.59", + "version": "1.10.65", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "e607609388d3a6d418a50a49f7940e8086798281" + "reference": "3c657d057a0b7ecae19cb12db446bbc99d8839c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e607609388d3a6d418a50a49f7940e8086798281", - "reference": "e607609388d3a6d418a50a49f7940e8086798281", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3c657d057a0b7ecae19cb12db446bbc99d8839c6", + "reference": "3c657d057a0b7ecae19cb12db446bbc99d8839c6", "shasum": "" }, "require": { @@ -6169,7 +6315,7 @@ "type": "tidelift" } ], - "time": "2024-02-20T13:59:13+00:00" + "time": "2024-03-23T10:30:26+00:00" }, { "name": "pimple/pimple", @@ -6783,16 +6929,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.0", + "version": "v0.12.2", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "750bf031a48fd07c673dbe3f11f72362ea306d0d" + "reference": "9185c66c2165bbf4d71de78a69dccf4974f9538d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/750bf031a48fd07c673dbe3f11f72362ea306d0d", - "reference": "750bf031a48fd07c673dbe3f11f72362ea306d0d", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/9185c66c2165bbf4d71de78a69dccf4974f9538d", + "reference": "9185c66c2165bbf4d71de78a69dccf4974f9538d", "shasum": "" }, "require": { @@ -6856,9 +7002,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.0" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.2" }, - "time": "2023-12-20T15:28:09+00:00" + "time": "2024-03-17T01:53:00+00:00" }, { "name": "purplepixie/phpdns", @@ -7196,16 +7342,16 @@ }, { "name": "rector/rector", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "7596fa6da06c6a20c012efe6bb3d9188a9113b11" + "reference": "c59507a9090b465d65e1aceed91e5b81986e375b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/7596fa6da06c6a20c012efe6bb3d9188a9113b11", - "reference": "7596fa6da06c6a20c012efe6bb3d9188a9113b11", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/c59507a9090b465d65e1aceed91e5b81986e375b", + "reference": "c59507a9090b465d65e1aceed91e5b81986e375b", "shasum": "" }, "require": { @@ -7240,7 +7386,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/1.0.2" + "source": "https://github.com/rectorphp/rector/tree/1.0.3" }, "funding": [ { @@ -7248,7 +7394,7 @@ "type": "github" } ], - "time": "2024-03-03T12:32:31+00:00" + "time": "2024-03-14T15:04:18+00:00" }, { "name": "resend/resend-laravel", @@ -7696,6 +7842,131 @@ ], "time": "2023-10-12T14:38:46+00:00" }, + { + "name": "socialiteproviders/manager", + "version": "v4.5.1", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Manager.git", + "reference": "a67f194f0f4c4c7616c549afc697b78df9658d44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/a67f194f0f4c4c7616c549afc697b78df9658d44", + "reference": "a67f194f0f4c4c7616c549afc697b78df9658d44", + "shasum": "" + }, + "require": { + "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0", + "laravel/socialite": "^5.2", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "SocialiteProviders\\Manager\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "SocialiteProviders\\Manager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andy Wendt", + "email": "andy@awendt.com" + }, + { + "name": "Anton Komarev", + "email": "a.komarev@cybercog.su" + }, + { + "name": "Miguel Piedrafita", + "email": "soy@miguelpiedrafita.com" + }, + { + "name": "atymic", + "email": "atymicq@gmail.com", + "homepage": "https://atymic.dev" + } + ], + "description": "Easily add new or override built-in providers in Laravel Socialite.", + "homepage": "https://socialiteproviders.com", + "keywords": [ + "laravel", + "manager", + "oauth", + "providers", + "socialite" + ], + "support": { + "issues": "https://github.com/socialiteproviders/manager/issues", + "source": "https://github.com/socialiteproviders/manager" + }, + "time": "2024-02-17T08:58:03+00:00" + }, + { + "name": "socialiteproviders/microsoft-azure", + "version": "5.2.0", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Microsoft-Azure.git", + "reference": "453d62c9d7e3b3b76e94c913fb46e68a33347b16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Microsoft-Azure/zipball/453d62c9d7e3b3b76e94c913fb46e68a33347b16", + "reference": "453d62c9d7e3b3b76e94c913fb46e68a33347b16", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.0", + "socialiteproviders/manager": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "SocialiteProviders\\Azure\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Hemmings", + "email": "chris@hemmin.gs" + } + ], + "description": "Microsoft Azure OAuth2 Provider for Laravel Socialite", + "keywords": [ + "azure", + "laravel", + "microsoft", + "oauth", + "provider", + "socialite" + ], + "support": { + "docs": "https://socialiteproviders.com/microsoft-azure", + "issues": "https://github.com/socialiteproviders/providers/issues", + "source": "https://github.com/socialiteproviders/providers" + }, + "time": "2024-03-15T03:02:10+00:00" + }, { "name": "spatie/backtrace", "version": "1.5.3", @@ -7760,29 +8031,29 @@ }, { "name": "spatie/laravel-activitylog", - "version": "4.7.3", + "version": "4.8.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-activitylog.git", - "reference": "ec65a478a909b8df1b4f0c3c45de2592ca7639e5" + "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/ec65a478a909b8df1b4f0c3c45de2592ca7639e5", - "reference": "ec65a478a909b8df1b4f0c3c45de2592ca7639e5", + "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/eb6f37dd40af950ce10cf5280f0acfa3e08c3bff", + "reference": "eb6f37dd40af950ce10cf5280f0acfa3e08c3bff", "shasum": "" }, "require": { - "illuminate/config": "^8.0 || ^9.0 || ^10.0", - "illuminate/database": "^8.69 || ^9.27 || ^10.0", - "illuminate/support": "^8.0 || ^9.0 || ^10.0", - "php": "^8.0", + "illuminate/config": "^8.0 || ^9.0 || ^10.0 || ^11.0", + "illuminate/database": "^8.69 || ^9.27 || ^10.0 || ^11.0", + "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0", + "php": "^8.1", "spatie/laravel-package-tools": "^1.6.3" }, "require-dev": { "ext-json": "*", - "orchestra/testbench": "^6.23 || ^7.0 || ^8.0", - "pestphp/pest": "^1.20" + "orchestra/testbench": "^6.23 || ^7.0 || ^8.0 || ^9.0", + "pestphp/pest": "^1.20 || ^2.0" }, "type": "library", "extra": { @@ -7835,7 +8106,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-activitylog/issues", - "source": "https://github.com/spatie/laravel-activitylog/tree/4.7.3" + "source": "https://github.com/spatie/laravel-activitylog/tree/4.8.0" }, "funding": [ { @@ -7847,7 +8118,7 @@ "type": "github" } ], - "time": "2023-01-25T17:04:51+00:00" + "time": "2024-03-08T22:28:17+00:00" }, { "name": "spatie/laravel-data", @@ -7936,16 +8207,16 @@ }, { "name": "spatie/laravel-package-tools", - "version": "1.16.2", + "version": "1.16.4", "source": { "type": "git", "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "e62eeb1fe8a8a0b2e83227a6c279c8c59f7d3a15" + "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/e62eeb1fe8a8a0b2e83227a6c279c8c59f7d3a15", - "reference": "e62eeb1fe8a8a0b2e83227a6c279c8c59f7d3a15", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53", + "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53", "shasum": "" }, "require": { @@ -7984,7 +8255,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.2" + "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.4" }, "funding": [ { @@ -7992,7 +8263,7 @@ "type": "github" } ], - "time": "2024-01-11T08:43:00+00:00" + "time": "2024-03-20T07:29:11+00:00" }, { "name": "spatie/laravel-ray", @@ -8209,16 +8480,16 @@ }, { "name": "spatie/php-structure-discoverer", - "version": "2.1.0", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/spatie/php-structure-discoverer.git", - "reference": "f5b3c935dda89d6c382b27e3caf348fa80bcfa88" + "reference": "24f5221641560ec0f7dce23dd814e7d555b0098b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/f5b3c935dda89d6c382b27e3caf348fa80bcfa88", - "reference": "f5b3c935dda89d6c382b27e3caf348fa80bcfa88", + "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/24f5221641560ec0f7dce23dd814e7d555b0098b", + "reference": "24f5221641560ec0f7dce23dd814e7d555b0098b", "shasum": "" }, "require": { @@ -8277,7 +8548,7 @@ ], "support": { "issues": "https://github.com/spatie/php-structure-discoverer/issues", - "source": "https://github.com/spatie/php-structure-discoverer/tree/2.1.0" + "source": "https://github.com/spatie/php-structure-discoverer/tree/2.1.1" }, "funding": [ { @@ -8285,7 +8556,7 @@ "type": "github" } ], - "time": "2024-02-16T12:42:24+00:00" + "time": "2024-03-13T16:08:30+00:00" }, { "name": "spatie/ray", @@ -8369,22 +8640,22 @@ }, { "name": "spatie/url", - "version": "2.3.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/spatie/url.git", - "reference": "ae324f5f77290827d66486fc88aa2c9373bc2170" + "reference": "93a51db743cdec22b081c64593e193887c9cd395" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/url/zipball/ae324f5f77290827d66486fc88aa2c9373bc2170", - "reference": "ae324f5f77290827d66486fc88aa2c9373bc2170", + "url": "https://api.github.com/repos/spatie/url/zipball/93a51db743cdec22b081c64593e193887c9cd395", + "reference": "93a51db743cdec22b081c64593e193887c9cd395", "shasum": "" }, "require": { "php": "^8.0", "psr/http-message": "^1.0 || ^2.0", - "spatie/macroable": "^2.0" + "spatie/macroable": "^1.0 || ^2.0" }, "require-dev": { "pestphp/pest": "^1.21" @@ -8415,7 +8686,7 @@ ], "support": { "issues": "https://github.com/spatie/url/issues", - "source": "https://github.com/spatie/url/tree/2.3.0" + "source": "https://github.com/spatie/url/tree/2.4.0" }, "funding": [ { @@ -8427,7 +8698,7 @@ "type": "github" } ], - "time": "2024-01-05T10:09:13+00:00" + "time": "2024-03-08T11:35:19+00:00" }, { "name": "stripe/stripe-php", @@ -11833,16 +12104,16 @@ }, { "name": "zbateson/mb-wrapper", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/zbateson/mb-wrapper.git", - "reference": "faf35dddfacfc5d4d5f9210143eafd7a7fe74334" + "reference": "09a8b77eb94af3823a9a6623dcc94f8d988da67f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/faf35dddfacfc5d4d5f9210143eafd7a7fe74334", - "reference": "faf35dddfacfc5d4d5f9210143eafd7a7fe74334", + "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/09a8b77eb94af3823a9a6623dcc94f8d988da67f", + "reference": "09a8b77eb94af3823a9a6623dcc94f8d988da67f", "shasum": "" }, "require": { @@ -11853,7 +12124,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "*", "phpstan/phpstan": "*", - "phpunit/phpunit": "<=9.0" + "phpunit/phpunit": "<10.0" }, "suggest": { "ext-iconv": "For best support/performance", @@ -11890,7 +12161,7 @@ ], "support": { "issues": "https://github.com/zbateson/mb-wrapper/issues", - "source": "https://github.com/zbateson/mb-wrapper/tree/1.2.0" + "source": "https://github.com/zbateson/mb-wrapper/tree/1.2.1" }, "funding": [ { @@ -11898,7 +12169,7 @@ "type": "github" } ], - "time": "2023-01-11T23:05:44+00:00" + "time": "2024-03-18T04:31:04+00:00" }, { "name": "zbateson/stream-decorators", @@ -12449,16 +12720,16 @@ }, { "name": "mockery/mockery", - "version": "1.6.7", + "version": "1.6.11", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06" + "reference": "81a161d0b135df89951abd52296adf97deb0723d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06", - "reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06", + "url": "https://api.github.com/repos/mockery/mockery/zipball/81a161d0b135df89951abd52296adf97deb0723d", + "reference": "81a161d0b135df89951abd52296adf97deb0723d", "shasum": "" }, "require": { @@ -12470,8 +12741,8 @@ "phpunit/phpunit": "<8.0" }, "require-dev": { - "phpunit/phpunit": "^8.5 || ^9.6.10", - "symplify/easy-coding-standard": "^12.0.8" + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" }, "type": "library", "autoload": { @@ -12528,7 +12799,7 @@ "security": "https://github.com/mockery/mockery/security/advisories", "source": "https://github.com/mockery/mockery" }, - "time": "2023-12-10T02:24:34+00:00" + "time": "2024-03-21T18:34:15+00:00" }, { "name": "myclabs/deep-copy", @@ -12687,35 +12958,35 @@ }, { "name": "pestphp/pest", - "version": "v2.34.1", + "version": "v2.34.5", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "78d9fd31d0bf50f9eb9daf855d69217e681b5e3e" + "reference": "863a0cc83744c677ffdb28a6a2b841dd049e57ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/78d9fd31d0bf50f9eb9daf855d69217e681b5e3e", - "reference": "78d9fd31d0bf50f9eb9daf855d69217e681b5e3e", + "url": "https://api.github.com/repos/pestphp/pest/zipball/863a0cc83744c677ffdb28a6a2b841dd049e57ce", + "reference": "863a0cc83744c677ffdb28a6a2b841dd049e57ce", "shasum": "" }, "require": { "brianium/paratest": "^7.3.1", - "nunomaduro/collision": "^7.10.0|^8.1.0", - "nunomaduro/termwind": "^1.15.1|^2.0.0", + "nunomaduro/collision": "^7.10.0|^8.1.1", + "nunomaduro/termwind": "^1.15.1|^2.0.1", "pestphp/pest-plugin": "^2.1.1", "pestphp/pest-plugin-arch": "^2.7.0", "php": "^8.1.0", - "phpunit/phpunit": "^10.5.11" + "phpunit/phpunit": "^10.5.15" }, "conflict": { - "phpunit/phpunit": ">10.5.11", + "phpunit/phpunit": ">10.5.15", "sebastian/exporter": "<5.1.0", "webmozart/assert": "<1.11.0" }, "require-dev": { "pestphp/pest-dev-tools": "^2.16.0", - "pestphp/pest-plugin-type-coverage": "^2.8.0", + "pestphp/pest-plugin-type-coverage": "^2.8.1", "symfony/process": "^6.4.0|^7.0.4" }, "bin": [ @@ -12779,7 +13050,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v2.34.1" + "source": "https://github.com/pestphp/pest/tree/v2.34.5" }, "funding": [ { @@ -12791,7 +13062,7 @@ "type": "github" } ], - "time": "2024-02-28T15:15:55+00:00" + "time": "2024-03-22T08:44:19+00:00" }, { "name": "pestphp/pest-plugin", @@ -13177,16 +13448,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.12", + "version": "10.1.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "842f72662d6b9edda84c4b6f13885fd9cd53dc63" + "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/842f72662d6b9edda84c4b6f13885fd9cd53dc63", - "reference": "842f72662d6b9edda84c4b6f13885fd9cd53dc63", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", + "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", "shasum": "" }, "require": { @@ -13243,7 +13514,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.12" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.14" }, "funding": [ { @@ -13251,7 +13522,7 @@ "type": "github" } ], - "time": "2024-03-02T07:22:05+00:00" + "time": "2024-03-12T15:33:41+00:00" }, { "name": "phpunit/php-file-iterator", @@ -13498,16 +13769,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.11", + "version": "10.5.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4" + "reference": "86376e05e8745ed81d88232ff92fee868247b07b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4", - "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/86376e05e8745ed81d88232ff92fee868247b07b", + "reference": "86376e05e8745ed81d88232ff92fee868247b07b", "shasum": "" }, "require": { @@ -13579,7 +13850,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.11" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.15" }, "funding": [ { @@ -13595,7 +13866,7 @@ "type": "tidelift" } ], - "time": "2024-02-25T14:05:00+00:00" + "time": "2024-03-22T04:17:47+00:00" }, { "name": "sebastian/cli-parser", @@ -13969,16 +14240,16 @@ }, { "name": "sebastian/environment", - "version": "6.0.1", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", "shasum": "" }, "require": { @@ -13993,7 +14264,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -14021,7 +14292,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" }, "funding": [ { @@ -14029,7 +14300,7 @@ "type": "github" } ], - "time": "2023-04-11T05:39:26+00:00" + "time": "2024-03-23T08:47:14+00:00" }, { "name": "sebastian/exporter", diff --git a/config/app.php b/config/app.php index 5851640be..b95224fdc 100644 --- a/config/app.php +++ b/config/app.php @@ -187,6 +187,7 @@ return [ /* * Package Service Providers... */ + \SocialiteProviders\Manager\ServiceProvider::class, /* * Application Service Providers... diff --git a/config/constants.php b/config/constants.php index 7bab10a56..54c451310 100644 --- a/config/constants.php +++ b/config/constants.php @@ -19,7 +19,9 @@ return [ ], ], 'services' => [ - 'official' => 'https://cdn.coollabs.io/coolify/service-templates.json', + // Temporary disabled until cache is implemented + // 'official' => 'https://cdn.coollabs.io/coolify/service-templates.json', + 'official' => 'https://raw.githubusercontent.com/coollabsio/coolify/main/templates/service-templates.json', ], 'limits' => [ 'trial_period' => 0, diff --git a/config/coolify.php b/config/coolify.php index 69ec23146..a6d6d8581 100644 --- a/config/coolify.php +++ b/config/coolify.php @@ -12,4 +12,6 @@ return [ 'is_windows_docker_desktop' => env('IS_WINDOWS_DOCKER_DESKTOP', false), 'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'), 'helper_image' => env('HELPER_IMAGE', 'ghcr.io/coollabsio/coolify-helper:latest'), + 'is_horizon_enabled' => env('HORIZON_ENABLED', true), + 'is_scheduler_enabled' => env('SCHEDULER_ENABLED', true), ]; diff --git a/config/sentry.php b/config/sentry.php index b4c1aa5f4..d7469ecfc 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -3,11 +3,11 @@ return [ // @see https://docs.sentry.io/product/sentry-basics/dsn-explainer/ - 'dsn' => 'https://f0b0e6be13926d4ac68d68d51d38db8f@o1082494.ingest.us.sentry.io/4505347448045568', + 'dsn' => 'https://89552af6db48f4ca6a871ec0fc42964d@o1082494.ingest.us.sentry.io/4505347448045568', // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.241', + 'release' => '4.0.0-beta.242', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/services.php b/config/services.php index 0ace530e8..db81eef9a 100644 --- a/config/services.php +++ b/config/services.php @@ -31,4 +31,11 @@ return [ 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), ], + 'azure' => [ + 'client_id' => env('AZURE_CLIENT_ID'), + 'client_secret' => env('AZURE_CLIENT_SECRET'), + 'redirect' => env('AZURE_REDIRECT_URI'), + 'tenant' => env('AZURE_TENANT_ID'), + 'proxy' => env('AZURE_PROXY'), + ], ]; diff --git a/config/version.php b/config/version.php index f00cd2d57..f67327b64 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ string('password')->nullable()->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->string('password')->nullable(false)->change(); + }); + } +}; diff --git a/database/migrations/2024_03_11_150013_create_oauth_settings.php b/database/migrations/2024_03_11_150013_create_oauth_settings.php new file mode 100644 index 000000000..c2178426d --- /dev/null +++ b/database/migrations/2024_03_11_150013_create_oauth_settings.php @@ -0,0 +1,33 @@ +id(); + $table->string('provider')->unique(); + $table->boolean('enabled')->default(false); + $table->string('client_id')->nullable(); + $table->text('client_secret')->nullable(); + $table->string('redirect_uri')->nullable(); + $table->string('tenant')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_settings'); + } +}; diff --git a/database/migrations/2024_03_22_080914_remove_popup_notifications.php b/database/migrations/2024_03_22_080914_remove_popup_notifications.php new file mode 100644 index 000000000..ccb270093 --- /dev/null +++ b/database/migrations/2024_03_22_080914_remove_popup_notifications.php @@ -0,0 +1,30 @@ +dropColumn('is_notification_sponsorship_enabled'); + $table->dropColumn('is_notification_notifications_enabled'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->boolean('is_notification_sponsorship_enabled')->default(true); + $table->boolean('is_notification_notifications_enabled')->default(true); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 2a2767d78..b3fac350f 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -32,6 +32,7 @@ class DatabaseSeeder extends Seeder StandalonePostgresqlSeeder::class, ScheduledDatabaseBackupSeeder::class, ScheduledDatabaseBackupExecutionSeeder::class, + OauthSettingSeeder::class, ]); } } diff --git a/database/seeders/OauthSettingSeeder.php b/database/seeders/OauthSettingSeeder.php new file mode 100644 index 000000000..4d33468c7 --- /dev/null +++ b/database/seeders/OauthSettingSeeder.php @@ -0,0 +1,37 @@ + 0, + 'provider' => 'azure', + ]); + OauthSetting::firstOrCreate([ + 'id' => 1, + 'provider' => 'bitbucket', + ]); + OauthSetting::firstOrCreate([ + 'id' => 2, + 'provider' => 'github', + ]); + OauthSetting::firstOrCreate([ + 'id' => 3, + 'provider' => 'gitlab', + ]); + OauthSetting::firstOrCreate([ + 'id' => 4, + 'provider' => 'google', + ]); + } +} diff --git a/database/seeders/ProductionSeeder.php b/database/seeders/ProductionSeeder.php index 4c66bdabf..206e92f76 100644 --- a/database/seeders/ProductionSeeder.php +++ b/database/seeders/ProductionSeeder.php @@ -198,5 +198,8 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== } catch (\Throwable $e) { echo "Error: {$e->getMessage()}\n"; } + + $oauth_settings_seeder = new OauthSettingSeeder(); + $oauth_settings_seeder->run(); } } diff --git a/docker/coolify-helper/Dockerfile b/docker/coolify-helper/Dockerfile index 4cf996904..5798c92bd 100644 --- a/docker/coolify-helper/Dockerfile +++ b/docker/coolify-helper/Dockerfile @@ -2,15 +2,15 @@ FROM alpine:3.17 ARG TARGETPLATFORM # https://download.docker.com/linux/static/stable/ -ARG DOCKER_VERSION=24.0.5 +ARG DOCKER_VERSION=24.0.9 # https://github.com/docker/compose/releases -ARG DOCKER_COMPOSE_VERSION=2.21.0 +ARG DOCKER_COMPOSE_VERSION=2.25.0 # https://github.com/docker/buildx/releases -ARG DOCKER_BUILDX_VERSION=0.11.2 +ARG DOCKER_BUILDX_VERSION=0.13.1 # https://github.com/buildpacks/pack/releases -ARG PACK_VERSION=0.32.1 +ARG PACK_VERSION=0.33.2 # https://github.com/railwayapp/nixpacks/releases -ARG NIXPACKS_VERSION=1.20.0 +ARG NIXPACKS_VERSION=1.21.2 USER root WORKDIR /artifacts @@ -34,7 +34,7 @@ RUN if [[ ${TARGETPLATFORM} == 'linux/arm64' ]]; then \ chmod +x ~/.docker/cli-plugins/docker-compose /usr/bin/docker /usr/local/bin/pack /root/.docker/cli-plugins/docker-buildx \ ;fi -COPY --from=minio/mc /usr/bin/mc /usr/bin/mc +COPY --from=minio/mc:RELEASE.2024-03-13T23-51-57Z /usr/bin/mc /usr/bin/mc RUN chmod +x /usr/bin/mc ENTRYPOINT ["/sbin/tini", "--"] diff --git a/docker/dev-ssu/Dockerfile b/docker/dev-ssu/Dockerfile index cf79afe4d..0c7ce2b2a 100644 --- a/docker/dev-ssu/Dockerfile +++ b/docker/dev-ssu/Dockerfile @@ -1,8 +1,8 @@ -FROM serversideup/php:8.2-fpm-nginx +FROM serversideup/php:8.2-fpm-nginx-v2.2.1 ARG TARGETPLATFORM # https://github.com/cloudflare/cloudflared/releases -ARG CLOUDFLARED_VERSION=2023.10.0 +ARG CLOUDFLARED_VERSION=2024.2.1 ARG POSTGRES_VERSION=15 RUN apt-get update @@ -40,4 +40,4 @@ RUN /bin/bash -c "if [[ ${TARGETPLATFORM} == 'linux/arm64' ]]; then \ RUN { \ echo 'upload_max_filesize=256M'; \ echo 'post_max_size=256M'; \ - } > /etc/php/current_version/cli/conf.d/upload-limits.ini \ No newline at end of file + } > /etc/php/current_version/cli/conf.d/upload-limits.ini diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/run b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/run index cec4f1dda..87471097e 100644 --- a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/run +++ b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/horizon/run @@ -1,5 +1,5 @@ #!/command/execlineb -P foreground { s6-sleep 5 - su - webuser -c "php /var/www/html/artisan horizon" + su - webuser -c "php /var/www/html/artisan start:horizon" } diff --git a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/scheduler-worker/run b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/scheduler-worker/run index 0f205c897..87ca0cae1 100644 --- a/docker/dev-ssu/etc/s6-overlay/s6-rc.d/scheduler-worker/run +++ b/docker/dev-ssu/etc/s6-overlay/s6-rc.d/scheduler-worker/run @@ -1,5 +1,5 @@ #!/command/execlineb -P foreground { s6-sleep 5 - su - webuser -c "php /var/www/html/artisan schedule:work" + su - webuser -c "php /var/www/html/artisan start:scheduler" } diff --git a/docker/prod-ssu/Dockerfile b/docker/prod-ssu/Dockerfile index d5ba465b7..dcc1c334d 100644 --- a/docker/prod-ssu/Dockerfile +++ b/docker/prod-ssu/Dockerfile @@ -1,21 +1,21 @@ -FROM serversideup/php:8.2-fpm-nginx as base +FROM serversideup/php:8.2-fpm-nginx-v2.2.1 as base WORKDIR /var/www/html COPY composer.json composer.lock ./ RUN composer install --no-dev --no-interaction --no-plugins --no-scripts --prefer-dist -FROM node:19 as static-assets +FROM node:20 as static-assets WORKDIR /app COPY . . COPY --from=base --chown=9999:9999 /var/www/html . RUN npm install RUN npm run build -FROM serversideup/php:8.2-fpm-nginx +FROM serversideup/php:8.2-fpm-nginx-v2.2.1 ARG TARGETPLATFORM # https://github.com/cloudflare/cloudflared/releases -ARG CLOUDFLARED_VERSION=2023.10.0 +ARG CLOUDFLARED_VERSION=2024.2.1 ARG POSTGRES_VERSION=15 WORKDIR /var/www/html @@ -66,4 +66,4 @@ RUN /bin/bash -c "if [[ ${TARGETPLATFORM} == 'linux/arm64' ]]; then \ RUN { \ echo 'upload_max_filesize=256M'; \ echo 'post_max_size=256M'; \ - } > /etc/php/current_version/cli/conf.d/upload-limits.ini \ No newline at end of file + } > /etc/php/current_version/cli/conf.d/upload-limits.ini diff --git a/lang/en.json b/lang/en.json index 1f4fbdb74..461a96e9a 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1,15 +1,21 @@ { "auth.login": "Login", + "auth.login.azure": "Login with Microsoft", + "auth.login.bitbucket": "Login with Bitbucket", + "auth.login.github": "Login with GitHub", + "auth.login.gitlab": "Login with Gitlab", + "auth.login.google": "Login with Google", "auth.already_registered": "Already registered?", "auth.confirm_password": "Confirm password", "auth.forgot_password": "Forgot password", "auth.forgot_password_send_email": "Send password reset email", - "auth.register_now": "Register a new account", + "auth.register_now": "Register", "auth.logout": "Logout", "auth.register": "Register", "auth.registration_disabled": "Registration is disabled. Please contact the administrator.", "auth.reset_password": "Reset password", "auth.failed": "These credentials do not match our records.", + "auth.failed.callback": "Failed to process callback from login provider.", "auth.failed.password": "The provided password is incorrect.", "auth.failed.email": "We can't find a user with that e-mail address.", "auth.throttle": "Too many login attempts. Please try again in :seconds seconds.", diff --git a/package-lock.json b/package-lock.json index b2124e9df..5d53421ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,19 +5,19 @@ "packages": { "": { "dependencies": { + "@tailwindcss/forms": "0.5.7", "@tailwindcss/typography": "0.5.10", - "alpinejs": "3.13.5", - "daisyui": "4.7.2", + "alpinejs": "3.13.7", "ioredis": "5.3.2", "tailwindcss-scrollbar": "0.1.0" }, "devDependencies": { "@vitejs/plugin-vue": "4.5.1", - "autoprefixer": "10.4.18", - "axios": "1.6.7", + "autoprefixer": "10.4.19", + "axios": "1.6.8", "laravel-echo": "1.16.0", "laravel-vite-plugin": "0.8.1", - "postcss": "8.4.35", + "postcss": "8.4.38", "pusher-js": "8.4.0-rc2", "tailwindcss": "3.4.1", "vite": "4.5.2", @@ -484,6 +484,17 @@ "node": ">= 8" } }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", + "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==", + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" + } + }, "node_modules/@tailwindcss/typography": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz", @@ -672,9 +683,9 @@ "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==" }, "node_modules/alpinejs": { - "version": "3.13.5", - "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.5.tgz", - "integrity": "sha512-1d2XeNGN+Zn7j4mUAKXtAgdc4/rLeadyTMWeJGXF5DzwawPBxwTiBhFFm6w/Ei8eJxUZeyNWWSD9zknfdz1kEw==", + "version": "3.13.7", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.7.tgz", + "integrity": "sha512-rcTyjTANbsePq1hb7eSekt3qjI94HLGeO6JaRjCssCVbIIc+qBrc7pO5S/+2JB6oojIibjM6FA+xRI3zhGPZIg==", "dependencies": { "@vue/reactivity": "~3.1.1" } @@ -708,9 +719,9 @@ "dev": true }, "node_modules/autoprefixer": { - "version": "10.4.18", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz", - "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", "dev": true, "funding": [ { @@ -728,7 +739,7 @@ ], "dependencies": { "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001591", + "caniuse-lite": "^1.0.30001599", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -745,12 +756,12 @@ } }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -829,9 +840,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001594", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz", - "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==", + "version": "1.0.30001600", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", + "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", "dev": true, "funding": [ { @@ -918,15 +929,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "node_modules/css-selector-tokenizer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz", - "integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==", - "dependencies": { - "cssesc": "^3.0.0", - "fastparse": "^1.1.2" - } - }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -944,32 +946,6 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "dev": true }, - "node_modules/culori": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/culori/-/culori-3.2.0.tgz", - "integrity": "sha512-HIEbTSP7vs1mPq/2P9In6QyFE0Tkpevh0k9a+FkjhD+cwsYm9WRSbn4uMdW9O0yXlNYC3ppxL3gWWPOcvEl57w==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/daisyui": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.7.2.tgz", - "integrity": "sha512-9UCss12Zmyk/22u+JbkVrHHxOzFOyY17HuqP5LeswI4hclbj6qbjJTovdj2zRy8cCH6/n6Wh0lTLjriGnyGh0g==", - "dependencies": { - "css-selector-tokenizer": "^0.8", - "culori": "^3", - "picocolors": "^1", - "postcss-js": "^4" - }, - "engines": { - "node": ">=16.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/daisyui" - } - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1109,11 +1085,6 @@ "node": ">= 6" } }, - "node_modules/fastparse": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" - }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -1134,9 +1105,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -1462,6 +1433,14 @@ "node": ">= 0.6" } }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1598,9 +1577,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "funding": [ { "type": "opencollective", @@ -1618,7 +1597,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -1876,9 +1855,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "engines": { "node": ">=0.10.0" } diff --git a/package.json b/package.json index 8568525e6..efedd03f0 100644 --- a/package.json +++ b/package.json @@ -7,20 +7,20 @@ }, "devDependencies": { "@vitejs/plugin-vue": "4.5.1", - "autoprefixer": "10.4.18", - "axios": "1.6.7", + "autoprefixer": "10.4.19", + "axios": "1.6.8", "laravel-echo": "1.16.0", "laravel-vite-plugin": "0.8.1", - "postcss": "8.4.35", + "postcss": "8.4.38", "pusher-js": "8.4.0-rc2", "tailwindcss": "3.4.1", "vite": "4.5.2", "vue": "3.4.21" }, "dependencies": { + "@tailwindcss/forms": "0.5.7", "@tailwindcss/typography": "0.5.10", - "alpinejs": "3.13.5", - "daisyui": "4.7.2", + "alpinejs": "3.13.7", "ioredis": "5.3.2", "tailwindcss-scrollbar": "0.1.0" } diff --git a/public/svgs/github.svg b/public/svgs/github.svg index 6c77b4144..270db203b 100644 --- a/public/svgs/github.svg +++ b/public/svgs/github.svg @@ -1 +1 @@ - + diff --git a/resources/css/app.css b/resources/css/app.css index 1080a84f4..f03e7e850 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -2,24 +2,168 @@ @tailwind components; @tailwind utilities; -html { - @apply text-neutral-400; +html, +body { + @apply h-full bg-neutral-100 text-neutral-800 dark:bg-base dark:text-neutral-400; } body { @apply text-sm antialiased scrollbar; } -button[isError] { - @apply bg-red-600 hover:bg-red-700; +.input, +.select { + @apply text-black dark:bg-coolgray-100 dark:text-white ring-neutral-300 dark:ring-coolgray-300; } -button[isHighlighted] { - @apply bg-coollabs hover:bg-coollabs-100; +/* Readonly */ +.input { + @apply dark:read-only:text-neutral-500 dark:read-only:ring-0 dark:read-only:bg-coolgray-100/40 placeholder:text-neutral-300 dark:placeholder:text-neutral-700 read-only:text-neutral-500 read-only:bg-neutral-200; } +/* Focus */ +.input, +.select { + @apply focus:ring-2 dark:focus:ring-coolgray-300 focus:ring-neutral-400; +} + +.input, +.select { + @apply block w-full py-1.5 rounded border-0 text-sm ring-1 ring-inset; +} + +.input[type='password'] { + @apply pr-10; +} + +option { + @apply dark:text-white dark:bg-coolgray-100; +} + +.button { + @apply flex items-center justify-center gap-2 px-3 py-1 text-sm font-normal normal-case rounded cursor-pointer bg-neutral-200 hover:bg-neutral-300 dark:bg-coolgray-200 dark:text-white dark:hover:bg-coolgray-100 dark:hover:dark:text-white dark:disabled:bg-coolgray-100/40 dark:disabled:text-neutral-800 disabled:bg-neutral-100 disabled:text-neutral-200 disabled:cursor-not-allowed min-w-fit hover:dark:text-white focus:outline-1 ; +} + +button[isError]:not(:disabled) { + @apply text-white bg-red-600 hover:bg-red-700; +} + +button[isHighlighted]:not(:disabled) { + @apply text-white bg-coollabs hover:bg-coollabs-100; +} + + +h1 { + @apply text-2xl font-bold dark:text-white; +} + +h2 { + @apply text-xl font-bold dark:text-white; +} + +h3 { + @apply text-lg font-bold dark:text-white; +} + +h4 { + @apply text-base font-bold dark:text-white; +} + +a { + @apply hover:text-black dark:hover:text-white; +} + +label { + @apply dark:text-neutral-400; +} + +table { + @apply min-w-full divide-y dark:divide-coolgray-200 divide-neutral-300; +} + +thead { + @apply uppercase; +} + +tbody { + @apply divide-y dark:divide-coolgray-200 divide-neutral-300; +} + +tr { + @apply text-neutral-400; +} + +tr th { + @apply px-3 py-3.5 text-left text-white; +} + +tr th:first-child { + @apply py-3.5 pl-4 pr-3 sm:pl-6; +} + +tr td { + @apply px-3 py-4 whitespace-nowrap; +} + +tr td:first-child { + @apply pl-4 pr-3 font-bold sm:pl-6; +} + +.alert-success { + @apply flex items-center gap-2 text-success; +} + +.alert-error { + @apply flex items-center gap-2 text-error; +} + +.dropdown-item { + @apply relative flex cursor-pointer select-none dark:text-white hover:bg-neutral-300 dark:hover:bg-coollabs items-center pr-4 pl-2 py-1 text-xs justify-start outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 gap-2 w-full; +} + +.badge { + @apply inline-block w-3 h-3 text-xs font-bold leading-none border rounded-full border-neutral-200 dark:border-black; +} + +.badge-success { + @apply bg-success; +} + +.badge-warning { + @apply bg-warning; +} + +.badge-error { + @apply bg-error; +} + +/* [type='checkbox']:checked { + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='black' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); +} */ + +.menu { + @apply flex items-center gap-1; +} + +.menu-item { + @apply flex items-center w-full gap-3 py-1 pl-2 dark:hover:bg-coolgray-100 dark:hover:text-white hover:bg-neutral-300; +} + +.menu-item-active { + @apply text-black rounded-none dark:bg-coolgray-200 dark:text-warning bg-neutral-200; +} + +.heading-item-active { + @apply text-black rounded-none dark:bg-coolgray-200 dark:text-warning; +} + +.icon { + @apply w-6 h-6 dark:hover:text-white; +} + + .scrollbar { - @apply scrollbar-thumb-coollabs-100 scrollbar-track-coolgray-200 scrollbar-w-2; + @apply scrollbar-thumb-coollabs-100 dark:scrollbar-track-coolgray-200 scrollbar-track-neutral-200 scrollbar-w-2; } .main { @@ -27,64 +171,43 @@ button[isHighlighted] { } .custom-modal { - @apply flex flex-col gap-2 px-8 py-4 border bg-base-100 border-coolgray-200; -} - -.label-text, -label { - @apply text-neutral-400; + @apply z-50 flex flex-col gap-2 px-8 py-4 border dark:bg-coolgray-100 dark:border-coolgray-200; } .navbar-main { - @apply flex items-end gap-6 py-2 border-b-2 border-solid border-coolgray-200; + @apply flex items-center h-10 gap-6 pb-2 border-b-2 border-solid dark:border-coolgray-200; } .loading { - @apply w-4 text-warning; -} - -h1 { - @apply text-3xl font-bold text-white; -} - -h2 { - @apply text-2xl font-bold text-white; -} - -h3 { - @apply text-xl font-bold text-white; -} - -h4 { - @apply text-base font-bold text-white; -} - -a { - @apply text-neutral-400 hover:text-white link link-hover hover:bg-transparent; + @apply w-4 dark:text-warning text-coollabs; } .kbd-custom { - @apply px-2 text-xs border border-dashed rounded border-neutral-700 text-warning; -} - -.icon { - @apply w-6 h-6; -} - -.icon:hover { - @apply text-white; + @apply px-2 text-xs border border-dashed rounded border-neutral-700 dark:text-warning; } .box { - @apply flex p-2 transition-colors cursor-pointer min-h-[4rem] bg-coolgray-100 hover:bg-coollabs-100 hover:text-white hover:no-underline; + @apply flex lg:flex-row flex-col p-2 transition-colors cursor-pointer min-h-[4rem] dark:bg-coolgray-100 bg-white border border-neutral-200 dark:border-black hover:bg-neutral-200 dark:hover:bg-coollabs-100 dark:hover:text-white hover:no-underline; +} + +.on-box { + @apply rounded hover:bg-neutral-300 dark:hover:bg-coolgray-500/20; } .box-without-bg { - @apply flex p-2 transition-colors hover:text-white hover:no-underline min-h-[4rem]; + @apply flex p-2 transition-colors dark:hover:text-white hover:no-underline min-h-[4rem]; +} + +.box-title { + @apply font-bold text-black dark:text-white group-hover:dark:text-white; +} + +.box-description { + @apply text-xs font-bold text-neutral-500 group-hover:dark:text-white group-hover:text-black; } .description { - @apply text-xs font-bold text-neutral-500 group-hover:text-white; + @apply text-xs font-bold text-neutral-500 group-hover:dark:text-white group-hover:text-black; } .lds-heart { @@ -122,56 +245,33 @@ a { } .text-helper { - @apply inline-block font-bold text-warning; + @apply inline-block font-bold text-coollabs dark:text-warning; } -table { - @apply min-w-full divide-y divide-coolgray-200; +.info-helper { + @apply cursor-pointer text-coollabs dark:text-warning; } -thead { - @apply uppercase; -} - -tbody { - @apply divide-y divide-coolgray-200; -} - -tr { - @apply text-neutral-400; -} - -tr th { - @apply px-3 py-3.5 text-left text-white; -} - -tr th:first-child { - @apply py-3.5 pl-4 pr-3 sm:pl-6; -} - -tr td { - @apply px-3 py-4 whitespace-nowrap; -} - -tr td:first-child { - @apply pl-4 pr-3 font-bold sm:pl-6; +.info-helper-popup { + @apply absolute z-40 hidden text-xs rounded text-neutral-700 group-hover:block dark:border-coolgray-500 border-neutral-900 dark:bg-coolgray-400 bg-neutral-200 dark:text-neutral-300; } .buyme { @apply block px-3 py-2 mt-10 text-sm font-semibold leading-6 text-center text-white rounded-md shadow-sm bg-coolgray-200 hover:bg-coolgray-300 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-coolgray-200 hover:no-underline; } +.title { + @apply hidden pb-0 lg:block lg:pb-8; +} + .subtitle { - @apply pt-2 pb-10; + @apply pt-2 pb-9; } .fullscreen { @apply fixed top-0 left-0 w-full h-full z-[9999] bg-coolgray-100 overflow-y-auto scrollbar pb-4; } -input.input-sm { - @apply pr-10; -} -option{ - @apply text-white; +.toast { + z-index: 1; } diff --git a/resources/js/components/MagicBar.vue b/resources/js/components/MagicBar.vue index 386a267b1..611ec0891 100644 --- a/resources/js/components/MagicBar.vue +++ b/resources/js/components/MagicBar.vue @@ -9,6 +9,7 @@ + / @@ -38,7 +39,7 @@ class="mt-4 mb-2 text-xs font-semibold text-neutral-500">{{ possibleSequences[sequenceState.sequence[sequenceState.currentActionIndex]].newTitle }} -