Summary / Описание проблемы
В local_db.dart сохранение метаданных подключения (в SQLite) и сохранение секретных данных (пароль и строка подключения в ConnectionSecretsStore через FlutterSecureStorage) происходят последовательно без атомарной транзакции и надлежащей обработки ошибок:
- В updateConnection (L374): Обновление записи в таблице connections выполняется в транзакции SQLite, после чего вызывается await ConnectionSecretsStore.writeForConnection(...). Если запись в системный хэранилище секретов (Keychain / libsecret) завершается ошибкой, запись в SQLite уже зафиксирована. Данные в UI рассинхронизируются, пароль теряется.
- В removeConnection (L397): Сначала вызывается await ConnectionSecretsStore.deleteForConnection(id);. Если удаление ключа из FlutterSecureStorage вызывает исключение (например, если ключ отсутствует или системный демон недоступен), метод прерывается с ошибкой, и удаление строки из SQLite (db.delete('connections')) вообще не выполняется. В результате пользователь не может удалить «битое» подключение из интерфейса приложения.
Scope & Component
- Scope: desktop
- Component: Core / Storage & Secrets
- Kind: bug
- Severity: high
- Detected in version: dev / 0.5.0
Местоположение в коде
- Файлы:
- lib/core/storage/local_db.dart (строки ~362-401, методы addConnection, updateConnection, removeConnection)
- lib/core/storage/connection_secrets_store.dart (строки ~19-28, методы write и delete)
Шаги воспроизведения
- В Linux отключить демон libsecret (или смоделировать сбой/отсутствие ключа в FlutterSecureStorage при удалении).
- Попытаться удалить существующее подключение в UI (removeConnection).
- Фактический результат: Исключение в ConnectionSecretsStore.deleteForConnection блокирует выполнение db.delete. Подключение остается в списке таблиц SQLite навсегда.
- Ожидаемый результат: Операции удаления из ConnectionSecretsStore должны быть обернуты в try-catch (или не блокировать удаление метаданных из SQLite), а добавление/обновление должно гарантировать согласованность состояния пароля и записи в БД.
Acceptance Criteria / Критерии приемки
- В removeConnection в local_db.dart удаление секрета из ConnectionSecretsStore.deleteForConnection(id) не блокирует удаление строки подключения из таблицы SQLite при возникновении ошибок хранилища.
- В addConnection и updateConnection добавлена корректная обработка сбоев записи в ConnectionSecretsStore (с откатом или явным предупреждением пользователя об ошибке сохранения пароля в OS Keychain).
Reactions are currently unavailable
Summary / Описание проблемы
В local_db.dart сохранение метаданных подключения (в SQLite) и сохранение секретных данных (пароль и строка подключения в ConnectionSecretsStore через FlutterSecureStorage) происходят последовательно без атомарной транзакции и надлежащей обработки ошибок:
Scope & Component
Местоположение в коде
Шаги воспроизведения
Acceptance Criteria / Критерии приемки