Merge branch 'next' into main
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\InstanceSettings;
|
||||
use Illuminate\Container\Attributes\Auth as AttributesAuth;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
@@ -32,7 +31,7 @@ class NavbarDeleteTeam extends Component
|
||||
$currentTeam->delete();
|
||||
|
||||
$currentTeam->members->each(function ($user) use ($currentTeam) {
|
||||
if ($user->id === AttributesAuth::id()) {
|
||||
if ($user->id === Auth::id()) {
|
||||
return;
|
||||
}
|
||||
$user->teams()->detach($currentTeam);
|
||||
|
||||
@@ -73,6 +73,9 @@ class Email extends Component
|
||||
#[Validate(['nullable', 'string'])]
|
||||
public ?string $resendApiKey = null;
|
||||
|
||||
#[Validate(['required', 'email'])]
|
||||
public string $testEmailAddress = '';
|
||||
|
||||
public function mount()
|
||||
{
|
||||
try {
|
||||
@@ -132,14 +135,21 @@ class Email extends Component
|
||||
}
|
||||
}
|
||||
|
||||
public function sendTestNotification()
|
||||
public function sendTestEmail()
|
||||
{
|
||||
try {
|
||||
$this->validate([
|
||||
'testEmailAddress' => 'required|email',
|
||||
], [
|
||||
'testEmailAddress.required' => 'Test email address is required.',
|
||||
'testEmailAddress.email' => 'Please enter a valid email address.',
|
||||
]);
|
||||
|
||||
$executed = RateLimiter::attempt(
|
||||
'test-email:'.$this->team->id,
|
||||
$perMinute = 0,
|
||||
function () {
|
||||
$this->team?->notify(new Test($this->emails));
|
||||
$this->team?->notify(new Test($this->testEmailAddress));
|
||||
$this->dispatch('success', 'Test Email sent.');
|
||||
},
|
||||
$decaySeconds = 10,
|
||||
|
||||
@@ -36,7 +36,11 @@ class Heading extends Component
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->parameters = [
|
||||
'project_uuid' => $this->application->project()->uuid,
|
||||
'environment_name' => $this->application->environment->name,
|
||||
'application_uuid' => $this->application->uuid,
|
||||
];
|
||||
$lastDeployment = $this->application->get_last_successful_deployment();
|
||||
$this->lastDeploymentInfo = data_get_str($lastDeployment, 'commit')->limit(7).' '.data_get($lastDeployment, 'commit_message');
|
||||
$this->lastDeploymentLink = $this->application->gitCommitLink(data_get($lastDeployment, 'commit'));
|
||||
@@ -45,13 +49,11 @@ class Heading extends Component
|
||||
public function check_status($showNotification = false)
|
||||
{
|
||||
if ($this->application->destination->server->isFunctional()) {
|
||||
GetContainersStatus::dispatch($this->application->destination->server)->onQueue('high');
|
||||
GetContainersStatus::dispatch($this->application->destination->server);
|
||||
}
|
||||
if ($showNotification) {
|
||||
$this->dispatch('success', 'Success', 'Application status updated.');
|
||||
}
|
||||
// Removed because it caused flickering
|
||||
// $this->dispatch('configurationChanged');
|
||||
}
|
||||
|
||||
public function force_deploy_without_cache()
|
||||
|
||||
@@ -21,8 +21,8 @@ class CreateScheduledBackup extends Component
|
||||
|
||||
public bool $enabled = true;
|
||||
|
||||
#[Validate(['required', 'integer'])]
|
||||
public int $s3StorageId;
|
||||
#[Validate(['nullable', 'integer'])]
|
||||
public ?int $s3StorageId = null;
|
||||
|
||||
public Collection $definedS3s;
|
||||
|
||||
@@ -49,6 +49,7 @@ class CreateScheduledBackup extends Component
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'enabled' => true,
|
||||
'frequency' => $this->frequency,
|
||||
@@ -58,6 +59,7 @@ class CreateScheduledBackup extends Component
|
||||
'database_type' => $this->database->getMorphClass(),
|
||||
'team_id' => currentTeam()->id,
|
||||
];
|
||||
|
||||
if ($this->database->type() === 'standalone-postgresql') {
|
||||
$payload['databases_to_backup'] = $this->database->postgres_db;
|
||||
} elseif ($this->database->type() === 'standalone-mysql') {
|
||||
@@ -72,11 +74,11 @@ class CreateScheduledBackup extends Component
|
||||
} else {
|
||||
$this->dispatch('refreshScheduledBackups');
|
||||
}
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
} finally {
|
||||
$this->frequency = '';
|
||||
$this->saveToS3 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,9 +91,12 @@ class Select extends Component
|
||||
{
|
||||
$services = get_service_templates(true);
|
||||
$services = collect($services)->map(function ($service, $key) {
|
||||
$logo = data_get($service, 'logo', 'svgs/coolify.png');
|
||||
|
||||
return [
|
||||
'name' => str($key)->headline(),
|
||||
'logo' => asset(data_get($service, 'logo', 'svgs/coolify.png')),
|
||||
'logo' => asset($logo),
|
||||
'logo_github_url' => 'https://raw.githubusercontent.com/coollabsio/coolify/refs/heads/main/public/a'.$logo,
|
||||
] + (array) $service;
|
||||
})->all();
|
||||
$gitBasedApplications = [
|
||||
|
||||
@@ -37,6 +37,7 @@ class Tags extends Component
|
||||
$this->validate();
|
||||
$tags = str($this->newTags)->trim()->explode(' ');
|
||||
foreach ($tags as $tag) {
|
||||
$tag = strip_tags($tag);
|
||||
if (strlen($tag) < 2) {
|
||||
$this->dispatch('error', 'Invalid tag.', "Tag <span class='dark:text-warning'>$tag</span> is invalid. Min length is 2.");
|
||||
|
||||
@@ -65,6 +66,7 @@ class Tags extends Component
|
||||
public function addTag(string $id, string $name)
|
||||
{
|
||||
try {
|
||||
$name = strip_tags($name);
|
||||
if ($this->resource->tags()->where('id', $id)->exists()) {
|
||||
$this->dispatch('error', 'Duplicate tags.', "Tag <span class='dark:text-warning'>$name</span> already added.");
|
||||
|
||||
|
||||
@@ -6,64 +6,60 @@ use App\Enums\ProxyTypes;
|
||||
use App\Models\Server;
|
||||
use App\Models\Team;
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class ByIp extends Component
|
||||
{
|
||||
#[Locked]
|
||||
public $private_keys;
|
||||
|
||||
#[Locked]
|
||||
public $limit_reached;
|
||||
|
||||
#[Validate('nullable|integer', as: 'Private Key')]
|
||||
public ?int $private_key_id = null;
|
||||
|
||||
#[Validate('nullable|string', as: 'Private Key Name')]
|
||||
public $new_private_key_name;
|
||||
|
||||
#[Validate('nullable|string', as: 'Private Key Description')]
|
||||
public $new_private_key_description;
|
||||
|
||||
#[Validate('nullable|string', as: 'Private Key Value')]
|
||||
public $new_private_key_value;
|
||||
|
||||
#[Validate('required|string', as: 'Name')]
|
||||
public string $name;
|
||||
|
||||
#[Validate('nullable|string', as: 'Description')]
|
||||
public ?string $description = null;
|
||||
|
||||
#[Validate('required|string', as: 'IP Address/Domain')]
|
||||
public string $ip;
|
||||
|
||||
#[Validate('required|string', as: 'User')]
|
||||
public string $user = 'root';
|
||||
|
||||
#[Validate('required|integer|between:1,65535', as: 'Port')]
|
||||
public int $port = 22;
|
||||
|
||||
#[Validate('required|boolean', as: 'Swarm Manager')]
|
||||
public bool $is_swarm_manager = false;
|
||||
|
||||
#[Validate('required|boolean', as: 'Swarm Worker')]
|
||||
public bool $is_swarm_worker = false;
|
||||
|
||||
#[Validate('nullable|integer', as: 'Swarm Cluster')]
|
||||
public $selected_swarm_cluster = null;
|
||||
|
||||
#[Validate('required|boolean', as: 'Build Server')]
|
||||
public bool $is_build_server = false;
|
||||
|
||||
#[Locked]
|
||||
public Collection $swarm_managers;
|
||||
|
||||
protected $rules = [
|
||||
'name' => 'required|string',
|
||||
'description' => 'nullable|string',
|
||||
'ip' => 'required',
|
||||
'user' => 'required|string',
|
||||
'port' => 'required|integer',
|
||||
'is_swarm_manager' => 'required|boolean',
|
||||
'is_swarm_worker' => 'required|boolean',
|
||||
'is_build_server' => 'required|boolean',
|
||||
];
|
||||
|
||||
protected $validationAttributes = [
|
||||
'name' => 'Name',
|
||||
'description' => 'Description',
|
||||
'ip' => 'IP Address/Domain',
|
||||
'user' => 'User',
|
||||
'port' => 'Port',
|
||||
'is_swarm_manager' => 'Swarm Manager',
|
||||
'is_swarm_worker' => 'Swarm Worker',
|
||||
'is_build_server' => 'Build Server',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->name = generate_random_name();
|
||||
@@ -88,6 +84,12 @@ class ByIp extends Component
|
||||
{
|
||||
$this->validate();
|
||||
try {
|
||||
if (Server::where('team_id', currentTeam()->id)
|
||||
->where('ip', $this->ip)
|
||||
->exists()) {
|
||||
return $this->dispatch('error', 'This IP/Domain is already in use by another server in your team.');
|
||||
}
|
||||
|
||||
if (is_null($this->private_key_id)) {
|
||||
return $this->dispatch('error', 'You must select a private key');
|
||||
}
|
||||
|
||||
@@ -107,6 +107,15 @@ class Show extends Component
|
||||
{
|
||||
if ($toModel) {
|
||||
$this->validate();
|
||||
|
||||
if (Server::where('team_id', currentTeam()->id)
|
||||
->where('ip', $this->ip)
|
||||
->where('id', '!=', $this->server->id)
|
||||
->exists()) {
|
||||
$this->ip = $this->server->ip;
|
||||
throw new \Exception('This IP/Domain is already in use by another server in your team.');
|
||||
}
|
||||
|
||||
$this->server->name = $this->name;
|
||||
$this->server->description = $this->description;
|
||||
$this->server->ip = $this->ip;
|
||||
|
||||
Reference in New Issue
Block a user