fix(api): return success false on access denied responses

Closes #12343

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-10-27 14:38:24 +01:00
co-authored by Claude Opus 5.5
parent 25761e29c4
commit 6b1dcc0c96
3 changed files with 55 additions and 2 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ class ApiAllowed
$isMcpRestBridge = $request->attributes->get('mcp_rest_bridge') === true;
if (! $isMcpRestBridge && instanceSettings()->is_api_enabled === false) {
return response()->json(['success' => true, 'message' => 'API is disabled.'], 403);
return response()->json(['success' => false, 'message' => 'API is disabled.'], 403);
}
return app(ApiIpAllowed::class)->handle($request, $next);
+1 -1
View File
@@ -23,7 +23,7 @@ class ApiIpAllowed
$allowedIps = array_filter(array_map('trim', explode(',', $allowedIps)));
if (! empty($allowedIps) && ! checkIPAgainstAllowlist(client_ip($request), $allowedIps)) {
return response()->json(['success' => true, 'message' => 'You are not allowed to access the API.'], 403);
return response()->json(['success' => false, 'message' => 'You are not allowed to access the API.'], 403);
}
return $next($request);
@@ -0,0 +1,53 @@
<?php
use App\Models\InstanceSettings;
use App\Models\Team;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Once;
uses(RefreshDatabase::class);
beforeEach(function () {
config()->set('constants.coolify.self_hosted', true);
InstanceSettings::forceCreate(['id' => 0, 'is_api_enabled' => true]);
$team = Team::factory()->create();
$user = User::factory()->create();
$team->members()->attach($user->id, ['role' => 'owner']);
session(['currentTeam' => $team]);
$this->token = $user->createToken('read', ['read'])->plainTextToken;
});
it('reports success false when the API is disabled', function () {
Once::flush();
// Postgres returns a real boolean; SQLite would return 0 for the uncast column.
InstanceSettings::get()->is_api_enabled = false;
$this->withToken($this->token)
->getJson('/api/v1/version')
->assertForbidden()
->assertExactJson(['success' => false, 'message' => 'API is disabled.']);
});
it('reports success false when the client IP is not in the allow-list', function () {
InstanceSettings::query()->where('id', 0)->update(['allowed_ips' => '192.0.2.10']);
Once::flush();
$this->withToken($this->token)
->getJson('/api/v1/version')
->assertForbidden()
->assertExactJson(['success' => false, 'message' => 'You are not allowed to access the API.']);
});
it('reports success false when the client IP is not in the allow-list on the IP-only route group', function () {
InstanceSettings::query()->where('id', 0)->update(['allowed_ips' => '192.0.2.10']);
Once::flush();
$this->withToken($this->token)
->getJson('/api/v1/disable')
->assertForbidden()
->assertExactJson(['success' => false, 'message' => 'You are not allowed to access the API.']);
});