diff --git a/app/Utilities/TeamSystemDatabaseProfile.php b/app/Utilities/TeamSystemDatabaseProfile.php index 27e2704e..f4cbaeca 100644 --- a/app/Utilities/TeamSystemDatabaseProfile.php +++ b/app/Utilities/TeamSystemDatabaseProfile.php @@ -17,10 +17,24 @@ class TeamSystemDatabaseProfile private const ITERATIONS = 210000; + /** + * 团队固定连接资料的加密版本。 + * + * 这里不包含数据库密码;系统数据库密码既用于解锁资料,也作为实际 + * 登录密码。资料必须保留在代码层,避免旧容器的 Laravel 配置缓存 + * 缺少新配置项时把新人挡在连接页面。 + */ + private const EMBEDDED_PROFILE = 'eyJ2IjoxLCJzYWx0IjoiMUNLdmVsREk4d3NBTTdUZGJsSDYydz09IiwiaXYiOiJaYW93YUM4YXYwZXMwd1oxIiwidGFnIjoiWUtpM3dJMXArZW1PY3Q0ZDlhaFF3Zz09IiwiZGF0YSI6ImxUaXZKZHVpVkF2R2RWM3Znd3hDVHViSVhKMFMzWWFwK1B3QUtcLzkyYm0wZnMzR05jZjZ2ZE5yeXZGbnlNelQ3d3JPbXNlc1B0MFpieWJhcDhkMktKMmZjb0lrZnRUdTBET1laZXc0VnFhRW5KR1VKQlNpaXZ5NXpYVmFVTWtLZnVMenNWNHEwZXc9PSJ9'; + public function __construct(private readonly ?string $encodedProfile = null) { } + public static function embeddedProfile(): string + { + return self::EMBEDDED_PROFILE; + } + public function settings(string $password): array { if ($password === '') { @@ -78,14 +92,10 @@ class TeamSystemDatabaseProfile { $profile = trim((string) ( $this->encodedProfile - ?? config('system_database.team_profile', '') + ?? config('system_database.team_profile') )); - if ($profile === '') { - throw new RuntimeException('团队系统数据库连接资料尚未安装,请联系负责人更新代码。'); - } - - return $profile; + return $profile !== '' ? $profile : self::EMBEDDED_PROFILE; } private function decrypt(string $encodedProfile, string $password): array diff --git a/config/system_database.php b/config/system_database.php index 580559a3..d77701cc 100644 --- a/config/system_database.php +++ b/config/system_database.php @@ -23,6 +23,6 @@ return [ */ 'team_profile' => env( 'TEAM_SYSTEM_DATABASE_PROFILE', - 'eyJ2IjoxLCJzYWx0IjoiMUNLdmVsREk4d3NBTTdUZGJsSDYydz09IiwiaXYiOiJaYW93YUM4YXYwZXMwd1oxIiwidGFnIjoiWUtpM3dJMXArZW1PY3Q0ZDlhaFF3Zz09IiwiZGF0YSI6ImxUaXZKZHVpVkF2R2RWM3Znd3hDVHViSVhKMFMzWWFwK1B3QUtcLzkyYm0wZnMzR05jZjZ2ZE5yeXZGbnlNelQ3d3JPbXNlc1B0MFpieWJhcDhkMktKMmZjb0lrZnRUdTBET1laZXc0VnFhRW5KR1VKQlNpaXZ5NXpYVmFVTWtLZnVMenNWNHEwZXc9PSJ9' + \App\Utilities\TeamSystemDatabaseProfile::embeddedProfile() ), ]; diff --git a/tests/Feature/SystemSettings/UpstreamDatabasesTest.php b/tests/Feature/SystemSettings/UpstreamDatabasesTest.php index 775e6716..3f673907 100644 --- a/tests/Feature/SystemSettings/UpstreamDatabasesTest.php +++ b/tests/Feature/SystemSettings/UpstreamDatabasesTest.php @@ -345,7 +345,10 @@ class UpstreamDatabasesTest extends FeatureTestCase public function test_wrong_system_database_password_stays_on_the_form(): void { - config(['system_database.mode' => 'bootstrap']); + config([ + 'system_database.mode' => 'bootstrap', + 'system_database.team_profile' => null, + ]); $this->withExceptionHandling(); $this->loginAs() diff --git a/tests/Unit/Utilities/TeamSystemDatabaseProfileTest.php b/tests/Unit/Utilities/TeamSystemDatabaseProfileTest.php index e2081d61..043946ce 100644 --- a/tests/Unit/Utilities/TeamSystemDatabaseProfileTest.php +++ b/tests/Unit/Utilities/TeamSystemDatabaseProfileTest.php @@ -43,4 +43,24 @@ class TeamSystemDatabaseProfileTest extends TestCase (new TeamSystemDatabaseProfile($encoded))->settings('wrong-password'); } + + public function test_missing_cached_config_uses_embedded_profile(): void + { + config(['system_database.team_profile' => null]); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('系统数据库密码不正确,请重新输入。'); + + (new TeamSystemDatabaseProfile())->settings('wrong-password'); + } + + public function test_empty_cached_config_uses_embedded_profile(): void + { + config(['system_database.team_profile' => '']); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('系统数据库密码不正确,请重新输入。'); + + (new TeamSystemDatabaseProfile())->settings('wrong-password'); + } }