'array', 'enabled' => 'boolean', ]; protected $hidden = ['password', 'shared_password']; public function getPasswordAttribute(?string $value): ?string { $shared = (string) ($this->attributes['shared_password'] ?? ''); if ($shared !== '') { return app(UpstreamCredentialCipher::class)->decrypt($shared); } return $value === null ? null : Crypt::decryptString($value); } public function setPasswordAttribute(?string $value): void { if ($value === null || $value === '') { $this->attributes['password'] = null; $this->attributes['shared_password'] = null; return; } // 同时保留 APP_KEY 旧密文,确保旧版本和紧急回滚仍可使用。 $this->attributes['password'] = Crypt::encryptString($value); $this->attributes['shared_password'] = app(UpstreamCredentialCipher::class)->encrypt($value); } public function resolvedPassword(): ?string { return $this->password; } public function sourceIdentifier(): string { // Legacy names stay stable; new connections need no manually assigned binding. return $this->source_key ?: 'database_' . $this->id; } }