fix(databases): refresh database form values consistently

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-09-28 12:07:02 +02:00
co-authored by Claude Opus 5.5
parent 0448c6ca51
commit 350d8a6571
10 changed files with 118 additions and 36 deletions
@@ -76,9 +76,6 @@ class General extends Component
}
$this->isPasswordHiddenForMember = auth()->user()?->isMember() ?? false;
if ($this->isPasswordHiddenForMember) {
$this->clickhouseAdminPassword = '';
}
}
protected function rules(): array
@@ -141,7 +138,8 @@ class General extends Component
$this->name = $this->database->name;
$this->description = $this->database->description;
$this->clickhouseAdminUser = $this->database->clickhouse_admin_user;
$this->clickhouseAdminPassword = $this->database->clickhouse_admin_password;
$canSeeCredentials = auth()->user()?->can('update', $this->database) ?? false;
$this->clickhouseAdminPassword = $canSeeCredentials ? $this->database->clickhouse_admin_password : '';
$this->image = $this->database->image;
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
@@ -74,9 +74,6 @@ class General extends Component
}
$this->isPasswordHiddenForMember = auth()->user()?->isMember() ?? false;
if ($this->isPasswordHiddenForMember) {
$this->dragonflyPassword = '';
}
}
protected function rules(): array
@@ -133,7 +130,8 @@ class General extends Component
} else {
$this->name = $this->database->name;
$this->description = $this->database->description;
$this->dragonflyPassword = $this->database->dragonfly_password;
$canSeeCredentials = auth()->user()?->can('update', $this->database) ?? false;
$this->dragonflyPassword = $canSeeCredentials ? $this->database->dragonfly_password : '';
$this->image = $this->database->image;
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
@@ -76,9 +76,6 @@ class General extends Component
}
$this->isPasswordHiddenForMember = auth()->user()?->isMember() ?? false;
if ($this->isPasswordHiddenForMember) {
$this->keydbPassword = '';
}
}
protected function rules(): array
@@ -138,7 +135,8 @@ class General extends Component
$this->name = $this->database->name;
$this->description = $this->database->description;
$this->keydbConf = $this->database->keydb_conf;
$this->keydbPassword = $this->database->keydb_password;
$canSeeCredentials = auth()->user()?->can('update', $this->database) ?? false;
$this->keydbPassword = $canSeeCredentials ? $this->database->keydb_password : '';
$this->image = $this->database->image;
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
@@ -130,10 +130,6 @@ class General extends Component
}
$this->isPasswordHiddenForMember = auth()->user()?->isMember() ?? false;
if ($this->isPasswordHiddenForMember) {
$this->mariadbRootPassword = '';
$this->mariadbPassword = '';
}
}
private function syncData(bool $toModel = false): void
@@ -158,9 +154,10 @@ class General extends Component
} else {
$this->name = $this->database->name;
$this->description = $this->database->description;
$this->mariadbRootPassword = $this->database->mariadb_root_password;
$canSeeCredentials = auth()->user()?->can('update', $this->database) ?? false;
$this->mariadbRootPassword = $canSeeCredentials ? $this->database->mariadb_root_password : '';
$this->mariadbUser = $this->database->mariadb_user;
$this->mariadbPassword = $this->database->mariadb_password;
$this->mariadbPassword = $canSeeCredentials ? $this->database->mariadb_password : '';
$this->mariadbDatabase = $this->database->mariadb_database;
$this->mariadbConf = $this->database->mariadb_conf;
$this->image = $this->database->image;
@@ -123,9 +123,6 @@ class General extends Component
}
$this->isPasswordHiddenForMember = auth()->user()?->isMember() ?? false;
if ($this->isPasswordHiddenForMember) {
$this->mongoInitdbRootPassword = '';
}
}
private function syncData(bool $toModel = false): void
@@ -151,7 +148,8 @@ class General extends Component
$this->description = $this->database->description;
$this->mongoConf = $this->database->mongo_conf;
$this->mongoInitdbRootUsername = $this->database->mongo_initdb_root_username;
$this->mongoInitdbRootPassword = $this->database->mongo_initdb_root_password;
$canSeeCredentials = auth()->user()?->can('update', $this->database) ?? false;
$this->mongoInitdbRootPassword = $canSeeCredentials ? $this->database->mongo_initdb_root_password : '';
$this->mongoInitdbDatabase = $this->database->mongo_initdb_database;
$this->image = $this->database->image;
$this->portsMappings = $this->database->ports_mappings;
@@ -130,10 +130,6 @@ class General extends Component
}
$this->isPasswordHiddenForMember = auth()->user()?->isMember() ?? false;
if ($this->isPasswordHiddenForMember) {
$this->mysqlRootPassword = '';
$this->mysqlPassword = '';
}
}
private function syncData(bool $toModel = false): void
@@ -158,9 +154,10 @@ class General extends Component
} else {
$this->name = $this->database->name;
$this->description = $this->database->description;
$this->mysqlRootPassword = $this->database->mysql_root_password;
$canSeeCredentials = auth()->user()?->can('update', $this->database) ?? false;
$this->mysqlRootPassword = $canSeeCredentials ? $this->database->mysql_root_password : '';
$this->mysqlUser = $this->database->mysql_user;
$this->mysqlPassword = $this->database->mysql_password;
$this->mysqlPassword = $canSeeCredentials ? $this->database->mysql_password : '';
$this->mysqlDatabase = $this->database->mysql_database;
$this->mysqlConf = $this->database->mysql_conf;
$this->image = $this->database->image;
@@ -144,9 +144,6 @@ class General extends Component
}
$this->isPasswordHiddenForMember = auth()->user()?->isMember() ?? false;
if ($this->isPasswordHiddenForMember) {
$this->postgresPassword = '';
}
}
private function syncData(bool $toModel = false): void
@@ -174,7 +171,8 @@ class General extends Component
$this->name = $this->database->name;
$this->description = $this->database->description;
$this->postgresUser = $this->database->postgres_user;
$this->postgresPassword = $this->database->postgres_password;
$canSeeCredentials = auth()->user()?->can('update', $this->database) ?? false;
$this->postgresPassword = $canSeeCredentials ? $this->database->postgres_password : '';
$this->postgresDb = $this->database->postgres_db;
$this->postgresInitdbArgs = $this->database->postgres_initdb_args;
$this->postgresHostAuthMethod = $this->database->postgres_host_auth_method;
@@ -122,9 +122,6 @@ class General extends Component
}
$this->isPasswordHiddenForMember = auth()->user()?->isMember() ?? false;
if ($this->isPasswordHiddenForMember) {
$this->redisPassword = '';
}
}
private function syncData(bool $toModel = false): void
@@ -155,7 +152,8 @@ class General extends Component
$this->customDockerRunOptions = $this->database->custom_docker_run_options;
$this->redisVersion = $this->database->getRedisVersion();
$this->redisUsername = $this->database->redis_username;
$this->redisPassword = $this->database->redis_password;
$canSeeCredentials = auth()->user()?->can('update', $this->database) ?? false;
$this->redisPassword = $canSeeCredentials ? $this->database->redis_password : '';
}
}
+1
View File
@@ -82,6 +82,7 @@ trait HasDatabaseStatusInfo
public function refresh(): void
{
$this->database->refresh();
$this->isPasswordHiddenForMember = ! (auth()->user()?->can('update', $this->database) ?? false);
if ($this->isPasswordHiddenForMember) {
$this->dbUrl = null;
$this->dbUrlPublic = null;
@@ -0,0 +1,99 @@
<?php
use App\Livewire\Project\Database\Clickhouse\General as ClickhouseGeneral;
use App\Livewire\Project\Database\Clickhouse\StatusInfo as ClickhouseStatusInfo;
use App\Livewire\Project\Database\Dragonfly\General as DragonflyGeneral;
use App\Livewire\Project\Database\Dragonfly\StatusInfo as DragonflyStatusInfo;
use App\Livewire\Project\Database\Keydb\General as KeydbGeneral;
use App\Livewire\Project\Database\Keydb\StatusInfo as KeydbStatusInfo;
use App\Livewire\Project\Database\Mariadb\General as MariadbGeneral;
use App\Livewire\Project\Database\Mariadb\StatusInfo as MariadbStatusInfo;
use App\Livewire\Project\Database\Mongodb\General as MongodbGeneral;
use App\Livewire\Project\Database\Mongodb\StatusInfo as MongodbStatusInfo;
use App\Livewire\Project\Database\Mysql\General as MysqlGeneral;
use App\Livewire\Project\Database\Mysql\StatusInfo as MysqlStatusInfo;
use App\Livewire\Project\Database\Postgresql\General as PostgresqlGeneral;
use App\Livewire\Project\Database\Postgresql\StatusInfo as PostgresqlStatusInfo;
use App\Livewire\Project\Database\Redis\General as RedisGeneral;
use App\Livewire\Project\Database\Redis\StatusInfo as RedisStatusInfo;
use App\Models\Environment;
use App\Models\InstanceSettings;
use App\Models\Project;
use App\Models\Server;
use App\Models\StandaloneDocker;
use App\Models\Team;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
uses(RefreshDatabase::class);
beforeEach(function () {
InstanceSettings::forceCreate(['id' => 0]);
$this->team = Team::factory()->create();
$this->owner = User::factory()->create();
$this->member = User::factory()->create();
$this->team->members()->attach($this->owner->id, ['role' => 'owner']);
$this->team->members()->attach($this->member->id, ['role' => 'member']);
$server = Server::factory()->create(['team_id' => $this->team->id]);
$this->destination = StandaloneDocker::where('server_id', $server->id)->first();
$project = Project::factory()->create(['team_id' => $this->team->id]);
$this->environment = Environment::factory()->create(['project_id' => $project->id]);
});
dataset('database-credential-components', [
'postgresql' => ['create_standalone_postgresql', PostgresqlGeneral::class, PostgresqlStatusInfo::class, ['postgres_password' => 'stored-db-credential'], ['postgresPassword']],
'mysql' => ['create_standalone_mysql', MysqlGeneral::class, MysqlStatusInfo::class, ['mysql_root_password' => 'stored-db-credential', 'mysql_password' => 'stored-db-credential'], ['mysqlRootPassword', 'mysqlPassword']],
'mariadb' => ['create_standalone_mariadb', MariadbGeneral::class, MariadbStatusInfo::class, ['mariadb_root_password' => 'stored-db-credential', 'mariadb_password' => 'stored-db-credential'], ['mariadbRootPassword', 'mariadbPassword']],
'mongodb' => ['create_standalone_mongodb', MongodbGeneral::class, MongodbStatusInfo::class, ['mongo_initdb_root_password' => 'stored-db-credential'], ['mongoInitdbRootPassword']],
'redis' => ['create_standalone_redis', RedisGeneral::class, RedisStatusInfo::class, ['redis_password' => 'stored-db-credential'], ['redisPassword']],
'keydb' => ['create_standalone_keydb', KeydbGeneral::class, KeydbStatusInfo::class, ['keydb_password' => 'stored-db-credential'], ['keydbPassword']],
'dragonfly' => ['create_standalone_dragonfly', DragonflyGeneral::class, DragonflyStatusInfo::class, ['dragonfly_password' => 'stored-db-credential'], ['dragonflyPassword']],
'clickhouse' => ['create_standalone_clickhouse', ClickhouseGeneral::class, ClickhouseStatusInfo::class, ['clickhouse_admin_password' => 'stored-db-credential'], ['clickhouseAdminPassword']],
]);
function createDatabaseWithCredential(string $createDatabase, array $credentials): mixed
{
return $createDatabase(test()->environment->id, test()->destination, $credentials)->fresh();
}
it('keeps database credentials out of member state after a refresh', function (string $createDatabase, string $generalClass, string $statusInfoClass, array $credentials, array $passwordProperties) {
$database = createDatabaseWithCredential($createDatabase, $credentials);
$this->actingAs($this->member);
session(['currentTeam' => $this->team]);
$general = Livewire::test($generalClass, ['database' => $database]);
if (method_exists($generalClass, 'refresh')) {
$general->call('refresh');
}
foreach ($passwordProperties as $property) {
$general->assertSet($property, '');
}
expect(json_encode($general->snapshot))->not->toContain('stored-db-credential');
$statusInfo = Livewire::test($statusInfoClass, ['database' => $database])
->set('isPasswordHiddenForMember', false)
->call('refresh')
->assertSet('dbUrl', null)
->assertSet('dbUrlPublic', null);
expect(json_encode($statusInfo->snapshot))->not->toContain('stored-db-credential');
})->with('database-credential-components');
it('keeps database credentials available to an owner', function (string $createDatabase, string $generalClass, string $statusInfoClass, array $credentials, array $passwordProperties) {
$database = createDatabaseWithCredential($createDatabase, $credentials);
$this->actingAs($this->owner);
session(['currentTeam' => $this->team]);
$general = Livewire::test($generalClass, ['database' => $database]);
foreach ($passwordProperties as $property) {
$general->assertSet($property, 'stored-db-credential');
}
Livewire::test($statusInfoClass, ['database' => $database])
->call('refresh')
->assertSet('dbUrl', $database->fresh()->internal_db_url);
})->with('database-credential-components');