Merge remote-tracking branch 'origin/next' into feat/api-destinations

This commit is contained in:
Andras Bacsai committed 2026-06-03 13:57:04 +02:00
commit 81cff9f486
359 files changed
+17162 -7179

No files matched your search

+1 -1
View File
@@ -4,4 +4,4 @@ use App\Mcp\Servers\CoolifyServer;
use Laravel\Mcp\Facades\Mcp;
Mcp::web('/mcp', CoolifyServer::class)
->middleware(['mcp.enabled', 'auth:sanctum']);
->middleware(['mcp.enabled', 'auth:sanctum', 'api.token.team']);
+4 -73
View File
@@ -12,12 +12,11 @@ use App\Http\Controllers\Api\ProjectController;
use App\Http\Controllers\Api\ResourcesController;
use App\Http\Controllers\Api\ScheduledTasksController;
use App\Http\Controllers\Api\SecurityController;
use App\Http\Controllers\Api\SentinelController;
use App\Http\Controllers\Api\ServersController;
use App\Http\Controllers\Api\ServicesController;
use App\Http\Controllers\Api\TeamController;
use App\Http\Middleware\ApiAllowed;
use App\Jobs\PushServerUpdateJob;
use App\Models\Server;
use Illuminate\Support\Facades\Route;
Route::get('/health', [OtherController::class, 'healthcheck']);
@@ -31,7 +30,7 @@ Route::post('/feedback', [OtherController::class, 'feedback'])
->middleware('throttle:feedback');
Route::group([
'middleware' => ['auth:sanctum', 'api.ability:write'],
'middleware' => ['auth:sanctum', 'api.token.team', 'api.ability:write'],
'prefix' => 'v1',
], function () {
Route::get('/enable', [OtherController::class, 'enable_api']);
@@ -40,7 +39,7 @@ Route::group([
Route::post('/mcp/disable', [OtherController::class, 'disable_mcp']);
});
Route::group([
'middleware' => ['auth:sanctum', ApiAllowed::class, 'api.sensitive'],
'middleware' => ['auth:sanctum', 'api.token.team', ApiAllowed::class, 'api.sensitive'],
'prefix' => 'v1',
], function () {
@@ -217,75 +216,7 @@ Route::group([
Route::group([
'prefix' => 'v1',
], function () {
Route::post('/sentinel/push', function () {
$token = request()->header('Authorization');
if (! $token) {
auditLogWebhookFailure('sentinel', 'token_missing');
return response()->json(['message' => 'Unauthorized'], 401);
}
$naked_token = str_replace('Bearer ', '', $token);
try {
$decrypted = decrypt($naked_token);
$decrypted_token = json_decode($decrypted, true);
} catch (Exception $e) {
auditLogWebhookFailure('sentinel', 'decrypt_failed');
return response()->json(['message' => 'Invalid token'], 401);
}
$server_uuid = data_get($decrypted_token, 'server_uuid');
if (! $server_uuid) {
auditLogWebhookFailure('sentinel', 'invalid_token_payload');
return response()->json(['message' => 'Invalid token'], 401);
}
$server = Server::where('uuid', $server_uuid)->first();
if (! $server) {
auditLogWebhookFailure('sentinel', 'server_not_found', [
'server_uuid' => $server_uuid,
]);
return response()->json(['message' => 'Server not found'], 404);
}
if (isCloud() && data_get($server->team->subscription, 'stripe_invoice_paid', false) === false && $server->team->id !== 0) {
auditLogWebhookFailure('sentinel', 'subscription_unpaid', [
'server_uuid' => $server->uuid,
'team_id' => $server->team_id,
]);
return response()->json(['message' => 'Unauthorized'], 401);
}
if ($server->isFunctional() === false) {
auditLogWebhookFailure('sentinel', 'server_not_functional', [
'server_uuid' => $server->uuid,
'team_id' => $server->team_id,
]);
return response()->json(['message' => 'Server is not functional'], 401);
}
if ($server->settings->sentinel_token !== $naked_token) {
auditLogWebhookFailure('sentinel', 'token_mismatch', [
'server_uuid' => $server->uuid,
'team_id' => $server->team_id,
]);
return response()->json(['message' => 'Unauthorized'], 401);
}
$data = request()->all();
// \App\Jobs\ServerCheckNewJob::dispatch($server, $data);
PushServerUpdateJob::dispatch($server, $data);
auditLog('sentinel.metrics_pushed', [
'server_uuid' => $server->uuid,
'team_id' => $server->team_id,
]);
return response()->json(['message' => 'ok'], 200);
});
Route::post('/sentinel/push', [SentinelController::class, 'push']);
});
Route::any('/{any}', function () {
+12 -4
View File
@@ -7,6 +7,7 @@ use App\Livewire\Admin\Index as AdminIndex;
use App\Livewire\Boarding\Index as BoardingIndex;
use App\Livewire\Dashboard;
use App\Livewire\Destination\Index as DestinationIndex;
use App\Livewire\Destination\Resources as DestinationResources;
use App\Livewire\Destination\Show as DestinationShow;
use App\Livewire\ForcePasswordReset;
use App\Livewire\Notifications\Discord as NotificationDiscord;
@@ -15,6 +16,7 @@ use App\Livewire\Notifications\Pushover as NotificationPushover;
use App\Livewire\Notifications\Slack as NotificationSlack;
use App\Livewire\Notifications\Telegram as NotificationTelegram;
use App\Livewire\Notifications\Webhook as NotificationWebhook;
use App\Livewire\Profile\Appearance as ProfileAppearance;
use App\Livewire\Profile\Index as ProfileIndex;
use App\Livewire\Project\Application\Configuration as ApplicationConfiguration;
use App\Livewire\Project\Application\Deployment\Index as DeploymentIndex;
@@ -33,7 +35,6 @@ use App\Livewire\Project\Service\DatabaseBackups as ServiceDatabaseBackups;
use App\Livewire\Project\Service\Index as ServiceIndex;
use App\Livewire\Project\Shared\ExecuteContainerCommand;
use App\Livewire\Project\Shared\Logs;
use App\Livewire\Project\Shared\ScheduledTask\Show as ScheduledTaskShow;
use App\Livewire\Project\Show as ProjectShow;
use App\Livewire\Security\ApiTokens;
use App\Livewire\Security\CloudInitScripts;
@@ -57,7 +58,8 @@ use App\Livewire\Server\Proxy\Show as ProxyShow;
use App\Livewire\Server\Resources as ResourcesShow;
use App\Livewire\Server\Security\Patches;
use App\Livewire\Server\Security\TerminalAccess;
use App\Livewire\Server\Sentinel as ServerSentinel;
use App\Livewire\Server\Sentinel\Logs as SentinelLogs;
use App\Livewire\Server\Sentinel\Show as SentinelShow;
use App\Livewire\Server\Show as ServerShow;
use App\Livewire\Server\Swarm as ServerSwarm;
use App\Livewire\Settings\Advanced as SettingsAdvanced;
@@ -125,6 +127,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/settings/scheduled-jobs', SettingsScheduledJobs::class)->name('settings.scheduled-jobs');
Route::get('/profile', ProfileIndex::class)->name('profile');
Route::get('/profile/appearance', ProfileAppearance::class)->name('profile.appearance');
Route::prefix('tags')->group(function () {
Route::get('/{tagName?}', TagsShow::class)->name('tags.show');
@@ -242,6 +245,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/servers', DatabaseConfiguration::class)->name('project.database.servers');
Route::get('/import-backup', DatabaseConfiguration::class)->name('project.database.import-backup')->middleware('can.update.resource');
Route::get('/persistent-storage', DatabaseConfiguration::class)->name('project.database.persistent-storage');
Route::get('/healthcheck', DatabaseConfiguration::class)->name('project.database.healthcheck');
Route::get('/webhooks', DatabaseConfiguration::class)->name('project.database.webhooks');
Route::get('/resource-limits', DatabaseConfiguration::class)->name('project.database.resource-limits');
Route::get('/resource-operations', DatabaseConfiguration::class)->name('project.database.resource-operations');
@@ -279,7 +283,8 @@ Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/', ServerShow::class)->name('server.show');
Route::get('/advanced', ServerAdvanced::class)->name('server.advanced');
Route::get('/swarm', ServerSwarm::class)->name('server.swarm');
Route::get('/sentinel', ServerSentinel::class)->name('server.sentinel');
Route::get('/sentinel', SentinelShow::class)->name('server.sentinel');
Route::get('/sentinel/logs', SentinelLogs::class)->name('server.sentinel.logs');
Route::get('/private-key', PrivateKeyShow::class)->name('server.private-key');
Route::get('/cloud-provider-token', CloudProviderTokenShow::class)->name('server.cloud-provider-token');
Route::get('/ca-certificate', CaCertificateShow::class)->name('server.ca-certificate');
@@ -287,7 +292,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/cloudflare-tunnel', CloudflareTunnel::class)->name('server.cloudflare-tunnel');
Route::get('/destinations', ServerDestinations::class)->name('server.destinations');
Route::get('/log-drains', LogDrains::class)->name('server.log-drains');
Route::get('/metrics', ServerCharts::class)->name('server.charts');
Route::get('/metrics', ServerCharts::class)->name('server.metrics');
Route::get('/danger', DeleteServer::class)->name('server.delete');
Route::get('/proxy', ProxyShow::class)->name('server.proxy');
Route::get('/proxy/dynamic', ProxyDynamicConfigurations::class)->name('server.proxy.dynamic-confs');
@@ -300,6 +305,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
});
Route::get('/destinations', DestinationIndex::class)->name('destination.index');
Route::get('/destination/{destination_uuid}', DestinationShow::class)->name('destination.show');
Route::get('/destination/{destination_uuid}/resources', DestinationResources::class)->name('destination.resources');
// Route::get('/security', fn () => view('security.index'))->name('security.index');
Route::get('/security/private-key', SecurityPrivateKeyIndex::class)->name('security.private-key.index');
@@ -320,6 +326,8 @@ Route::middleware(['auth'])->group(function () {
]);
})->name('source.all');
Route::get('/source/github/{github_app_uuid}', GitHubChange::class)->name('source.github.show');
Route::get('/source/github/{github_app_uuid}/permissions', GitHubChange::class)->name('source.github.permissions');
Route::get('/source/github/{github_app_uuid}/resources', GitHubChange::class)->name('source.github.resources');
});
Route::middleware(['auth'])->group(function () {
+5 -2
View File
@@ -7,8 +7,11 @@ use App\Http\Controllers\Webhook\Gitlab;
use App\Http\Controllers\Webhook\Stripe;
use Illuminate\Support\Facades\Route;
Route::get('/source/github/redirect', [Github::class, 'redirect']);
Route::get('/source/github/install', [Github::class, 'install']);
Route::middleware(['web', 'auth', 'throttle:30,1'])->group(function () {
Route::get('/source/github/redirect', [Github::class, 'redirect']);
Route::get('/source/github/install', [Github::class, 'install']);
});
Route::post('/source/github/events', [Github::class, 'normal']);
Route::post('/source/github/events/manual', [Github::class, 'manual']);