From d00df7425752c5bcf9ce7f93b1c2c8853659fce6 Mon Sep 17 00:00:00 2001 From: RyuJongJin <266630912+RyuJongJin@users.noreply.github.com> Date: Sat, 17 Oct 2026 22:32:14 +0900 Subject: [PATCH] =?UTF-8?q?WIP=20=EC=B5=9C=EC=83=81=20=C2=B7=20=EB=A7=88?= =?UTF-8?q?=EC=8A=A4=ED=84=B0=20=EC=B4=88=EA=B8=B0=ED=99=94=20"=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EB=90=9C=20=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8=20?= =?UTF-8?q?=C2=B7=20API=20=ED=82=A4"=20=EA=B0=80=20AI=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20API=20=ED=82=A4=EB=8F=84=20=EC=A7=80=EC=9A=B0?= =?UTF-8?q?=EA=B2=8C=20(=EB=B2=84=EA=B7=B8,=20=EA=B4=80=EB=A6=AC=EC=9E=90?= =?UTF-8?q?=20=EA=B2=B0=EC=A0=95)=20(=EA=B2=80=ED=86=A0=20=EB=8C=80?= =?UTF-8?q?=EA=B8=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 관리자 결정 (10/17): 문구는 "비밀번호 · API 키" 인데 AI 서비스 API 키 (ai.*) 는 남았다 (예전부터) → 함께 지운다. SFTP 비밀 값 (비밀번호 · 개인 키 · 키 암호) 은 88 1/3 에서 이미 넣음. 목록 · 아이디 · 주소 · 믿은 서버 키는 남김. 시험: 실제 SettingsStore + 메모리 안전 저장소로 os. · dav. · sftp. · ai. 값 7개를 넣고 지운 뒤 하나도 없음. Co-Authored-By: Claude Opus 5.5 --- lib/ui/master_prompt.dart | 2 ++ test/master_lock_test.dart | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lib/ui/master_prompt.dart b/lib/ui/master_prompt.dart index dca8318..e4388dc 100644 --- a/lib/ui/master_prompt.dart +++ b/lib/ui/master_prompt.dart @@ -142,6 +142,8 @@ Future clearStoredSecrets(AppController c) => c.updateSettings((s) => s ..webdavServers = [for (final x in s.webdavServers) x.copyWith(password: '')] // 88: SFTP 의 비밀번호 · 개인 키 · 키 암호도 (믿은 호스트 키는 비밀이 아니라 남김) ..sftpServers = [for (final x in s.sftpServers) x.copyWith(password: '', privateKey: '', keyPassphrase: '')] + // AI 서비스 API 키도 (문구 "비밀번호 · API 키" 와 같게 - 예전에는 남았다, 관리자 결정 10/17) + ..aiServices = [for (final x in s.aiServices) x.copyWith(apiKey: '')] ..openSubtitlesKey = '' ..openSubtitlesPassword = ''); diff --git a/test/master_lock_test.dart b/test/master_lock_test.dart index 193a96c..b1dd73a 100644 --- a/test/master_lock_test.dart +++ b/test/master_lock_test.dart @@ -7,13 +7,16 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:jj_mkvmaker/app/app_controller.dart'; import 'package:jj_mkvmaker/app/master_lock.dart'; import 'package:jj_mkvmaker/app/settings.dart'; +import 'package:jj_mkvmaker/core/sftp.dart'; import 'package:jj_mkvmaker/core/webdav.dart'; import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart'; import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart'; import 'package:jj_mkvmaker/services/platform_services.dart'; +import 'package:jj_mkvmaker/services/image_ai.dart' show AiService; import 'package:jj_mkvmaker/services/secret_store.dart'; import 'package:jj_mkvmaker/ui/master_prompt.dart'; import 'package:jj_mkvmaker/ui/settings_page.dart'; +import 'package:path/path.dart' as p; String hex(List b) => b.map((x) => x.toRadixString(16).padLeft(2, '0')).join(); @@ -272,6 +275,29 @@ void main() { expect(lock.unlocked, isFalse); }); + test('"저장된 비밀번호 · API 키" 지우기: 안전 저장소의 os. · dav. · sftp. · ai. 값이 모두 없어진다 (AI 키가 남던 것 - 관리자 10/17)', () async { + final tmp = Directory.systemTemp.createTempSync('jj_master_clear_'); + addTearDown(() => tmp.deleteSync(recursive: true)); + final secrets = MemorySecretStore(); + final store = SettingsStore(p.join(tmp.path, 'settings.json'), secrets); + final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()), + settingsStore: store); + await c.updateSettings((s) => s + ..openSubtitlesKey = 'k' + ..openSubtitlesPassword = 'op' + ..webdavServers = [const DavServer(id: 'd1', name: 'n', url: 'https://x', user: 'u', password: 'dp')] + ..sftpServers = [const SftpServer(id: 's1', name: 'n', host: 'h', user: 'u', password: 'sp', privateKey: 'PRIVATE KEY', keyPassphrase: 'kp')] + ..aiServices = [const AiService(id: 'a1', name: 'n', url: 'https://ai', kind: 'openai', apiKey: 'ak')]); + await store.save(c.settings); + bool secret(String k) => k.startsWith('os.') || k.startsWith('dav.pw.') || k.startsWith('sftp.') || k.startsWith('ai.'); + expect(secrets.values.keys.where(secret).length, 7, reason: '넣은 비밀 값이 저장소에 있다 (os 2 · dav 1 · sftp 3 · ai 1)'); + await clearStoredSecrets(c); + await store.save(c.settings); + expect(secrets.values.keys.where(secret), isEmpty); + // 목록 · 아이디 · 믿은 서버 키는 남김 + expect((c.settings.webdavServers.single.user, c.settings.sftpServers.single.user, c.settings.aiServices.single.url), ('u', 'u', 'https://ai')); + }); + test('최상으로 "앱 설정 전체" 를 지우면 처음 상태', () async { final c = controller()..settings.explorerLayout = 'single'; await resetAllSettings(c);