Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
375 changes: 239 additions & 136 deletions app/Http/Controllers/Api/ApplicationsController.php

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions bootstrap/helpers/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,5 @@ function removeUnnecessaryFieldsFromRequest(Request $request)
$request->offsetUnset('private_key_uuid');
$request->offsetUnset('use_build_server');
$request->offsetUnset('is_static');
$request->offsetUnset('force_domain_override');
}
98 changes: 98 additions & 0 deletions bootstrap/helpers/domains.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use App\Models\Application;
use App\Models\ServiceApplication;
use Illuminate\Support\Collection;

function checkDomainUsage(ServiceApplication|Application|null $resource = null, ?string $domain = null)
{
Expand Down Expand Up @@ -137,3 +138,100 @@ function checkDomainUsage(ServiceApplication|Application|null $resource = null,
'hasConflicts' => count($conflicts) > 0,
];
}

function checkIfDomainIsAlreadyUsedViaAPI(Collection|array $domains, ?string $teamId = null, ?string $uuid = null)
{
$conflicts = [];

if (is_null($teamId)) {
return ['error' => 'Team ID is required.'];
}
if (is_array($domains)) {
$domains = collect($domains);
}

$domains = $domains->map(function ($domain) {
if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/');
}

return str($domain);
});

// Check applications within the same team
$applications = Application::ownedByCurrentTeamAPI($teamId)->get(['fqdn', 'uuid', 'name', 'id']);
$serviceApplications = ServiceApplication::ownedByCurrentTeamAPI($teamId)->with('service:id,name')->get(['fqdn', 'uuid', 'id', 'service_id']);

if ($uuid) {
$applications = $applications->filter(fn ($app) => $app->uuid !== $uuid);
$serviceApplications = $serviceApplications->filter(fn ($app) => $app->uuid !== $uuid);
}

foreach ($applications as $app) {
if (is_null($app->fqdn)) {
continue;
}
$list_of_domains = collect(explode(',', $app->fqdn))->filter(fn ($fqdn) => $fqdn !== '');
foreach ($list_of_domains as $domain) {
if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/');
}
$naked_domain = str($domain)->value();
if ($domains->contains($naked_domain)) {
$conflicts[] = [
'domain' => $naked_domain,
'resource_name' => $app->name,
'resource_uuid' => $app->uuid,
'resource_type' => 'application',
'message' => "Domain $naked_domain is already in use by application '{$app->name}'",
];
}
}
}

foreach ($serviceApplications as $app) {
if (str($app->fqdn)->isEmpty()) {
continue;
}
$list_of_domains = collect(explode(',', $app->fqdn))->filter(fn ($fqdn) => $fqdn !== '');
foreach ($list_of_domains as $domain) {
if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/');
}
$naked_domain = str($domain)->value();
if ($domains->contains($naked_domain)) {
$conflicts[] = [
'domain' => $naked_domain,
'resource_name' => $app->service->name ?? 'Unknown Service',
'resource_uuid' => $app->uuid,
'resource_type' => 'service',
'message' => "Domain $naked_domain is already in use by service '{$app->service->name}'",
];
}
}
}

// Check instance-level domain
$settings = instanceSettings();
if (data_get($settings, 'fqdn')) {
$domain = data_get($settings, 'fqdn');
if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/');
}
$naked_domain = str($domain)->value();
if ($domains->contains($naked_domain)) {
$conflicts[] = [
'domain' => $naked_domain,
'resource_name' => 'Coolify Instance',
'resource_uuid' => null,
'resource_type' => 'instance',
'message' => "Domain $naked_domain is already in use by this Coolify instance",
];
}
}

return [
'conflicts' => $conflicts,
'hasConflicts' => count($conflicts) > 0,
];
}
73 changes: 0 additions & 73 deletions bootstrap/helpers/shared.php
Original file line number Diff line number Diff line change
Expand Up @@ -1084,79 +1084,6 @@ function check_ip_against_allowlist($ip, $allowlist)

return false;
}
function checkIfDomainIsAlreadyUsed(Collection|array $domains, ?string $teamId = null, ?string $uuid = null)
{
if (is_null($teamId)) {
return response()->json(['error' => 'Team ID is required.'], 400);
}
if (is_array($domains)) {
$domains = collect($domains);
}

$domains = $domains->map(function ($domain) {
if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/');
}

return str($domain);
});
$applications = Application::ownedByCurrentTeamAPI($teamId)->get(['fqdn', 'uuid']);
$serviceApplications = ServiceApplication::ownedByCurrentTeamAPI($teamId)->get(['fqdn', 'uuid']);
if ($uuid) {
$applications = $applications->filter(fn ($app) => $app->uuid !== $uuid);
$serviceApplications = $serviceApplications->filter(fn ($app) => $app->uuid !== $uuid);
}
$domainFound = false;
foreach ($applications as $app) {
if (is_null($app->fqdn)) {
continue;
}
$list_of_domains = collect(explode(',', $app->fqdn))->filter(fn ($fqdn) => $fqdn !== '');
foreach ($list_of_domains as $domain) {
if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/');
}
$naked_domain = str($domain)->value();
if ($domains->contains($naked_domain)) {
$domainFound = true;
break;
}
}
}
if ($domainFound) {
return true;
}
foreach ($serviceApplications as $app) {
if (str($app->fqdn)->isEmpty()) {
continue;
}
$list_of_domains = collect(explode(',', $app->fqdn))->filter(fn ($fqdn) => $fqdn !== '');
foreach ($list_of_domains as $domain) {
if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/');
}
$naked_domain = str($domain)->value();
if ($domains->contains($naked_domain)) {
$domainFound = true;
break;
}
}
}
if ($domainFound) {
return true;
}
$settings = instanceSettings();
if (data_get($settings, 'fqdn')) {
$domain = data_get($settings, 'fqdn');
if (str($domain)->endsWith('/')) {
$domain = str($domain)->beforeLast('/');
}
$naked_domain = str($domain)->value();
if ($domains->contains($naked_domain)) {
return true;
}
}
}

function parseCommandsByLineForSudo(Collection $commands, Server $server): array
{
Expand Down
Loading